如何在Go语言中解析JSONL格式文件并将数据存储到结构体
解决方法
你不需要引入第三方的go-simple-serializer依赖,直接用Go标准库的bufio和encoding/json就可以完成JSONL格式的解析,流程如下:
1. 定义对应结构体
首先声明匹配JSON字段的结构体,注意字段首字母必须大写,同时用json标签映射下划线命名的字段:
type CompanyPerson struct { CompanyID string `json:"company_id"` PeopleID string `json:"people_id"` Name string `json:"name"` Linkedin string `json:"linkedin"` JobTitle string `json:"job_title"` ImageBucketURL string `json:"image_bucket_url,omitempty"` }
其中omitempty标识是为了适配部分缺失image_bucket_url的记录,避免解码报错,缺失时该字段会默认赋值为空字符串。
2. 流式解析JSONL内容
不管你是直接从S3获取文件流(AWS SDK返回的GetObjectOutput.Body实现了io.Reader接口),还是先把文件下载到本地读取,都可以用逐行扫描的方式解析,不需要把整个文件加载到内存,大文件场景下性能更好:
package main import ( "bufio" "encoding/json" "fmt" "io" "os" ) func ParseJSONL(r io.Reader) ([]CompanyPerson, error) { var res []CompanyPerson scanner := bufio.NewScanner(r) // 可选:如果单行JSON长度超过默认的64KB,可以调整缓冲区大小 // buf := make([]byte, 1024*1024) // 1MB缓冲区 // scanner.Buffer(buf, bufio.MaxScanTokenSize) lineNum := 0 for scanner.Scan() { lineNum++ line := scanner.Bytes() // 跳过空行 if len(line) == 0 { continue } var person CompanyPerson if err := json.Unmarshal(line, &person); err != nil { return nil, fmt.Errorf("第%d行解析失败: %w", lineNum, err) } res = append(res, person) } if err := scanner.Err(); err != nil { return nil, fmt.Errorf("读取文件失败: %w", err) } return res, nil } // 调用示例:读取本地company.json文件 // func main() { // f, err := os.Open("company.json") // if err != nil { // panic(err) // } // defer f.Close() // persons, err := ParseJSONL(f) // if err != nil { // panic(err) // } // fmt.Printf("共解析到%d条记录\n", len(persons)) // }
注意事项
- 不要尝试把整个JSONL文件内容一次性用
json.Unmarshal解析:JSONL格式本身不是合法的JSON数组,整体解析会直接报错。 - 如果你的S3文件特别大,也可以不用把所有解析结果存在切片里,逐行处理即可,进一步降低内存占用。
内容的提问来源于stack exchange,提问作者Asaduzzaman Sohel
相关产品推荐
相关产品推荐

