如何获取CSV文件的总行数,解决读取后文件指针在末尾的问题及其他实现方法
问题处理方案
现有代码的指针偏移修复方法
你当前调用ReadAll()获取行数后文件指针会移动到文件末尾,仅需在读取行数后重置指针到文件起始位置即可,操作代码示例如下:
reader := csv.NewReader(fs) rows, err := reader.ReadAll() if err != nil { // 自定义错误处理逻辑 } rowCount := len(rows) // 此处替换为你的行数校验规则 if rowCount > 10 { // 重置文件指针到开头 _, err = fs.Seek(0, io.SeekStart) if err != nil { // 自定义错误处理逻辑 } // 重新创建reader即可从头解析文件 newReader := csv.NewReader(fs) // 后续解析逻辑 }
注意:该方案要求你使用的fs文件对象实现了io.Seeker接口,本地文件默认支持该接口,如果你使用的是网络流等不可寻址的文件对象则无法使用该方法。
其他获取CSV总行数的方案
- 逐行读取计数,适合大文件场景,不需要将全部内容加载到内存:
rowCount := 0 reader := csv.NewReader(fs) for { _, err := reader.Read() if err == io.EOF { break } if err != nil { // 自定义错误处理逻辑 } rowCount++ } // 计数完成后同样调用Seek重置指针即可 _, err = fs.Seek(0, io.SeekStart)
- 直接按换行符统计行数,性能最高,适合不需要校验CSV格式合法性的场景:
buf := make([]byte, 32*1024) rowCount := 0 lineSep := '\n' for { n, err := fs.Read(buf) for i := 0; i < n; i++ { if buf[i] == byte(lineSep) { rowCount++ } } if err == io.EOF { break } if err != nil { // 自定义错误处理逻辑 } } // 计数完成后重置指针 _, err = fs.Seek(0, io.SeekStart)
注意:该方案统计的行数会包含CSV单元格内的换行,如果你使用的CSV存在单元格内换行的情况,统计结果会比实际数据行数多,请确认格式后再使用。
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

