如何读取大型平面文件
来源:Golang技术栈
时间:2023-03-31 17:24:35 312浏览 收藏
“纵有疾风来,人生不言弃”,这句话送给正在学习Golang的朋友们,也希望在阅读本文《如何读取大型平面文件》后,能够真的帮助到大家。我也会在后续的文章中,陆续更新Golang相关的技术文章,有好的建议欢迎大家在评论留言,非常感谢!
问题内容
我有一个平面文件,其中包含 339276 行文本,大小为 62.1 MB。我正在尝试读取所有行,根据我拥有的某些条件解析它们,然后将它们插入数据库。
我最初尝试使用 bufio.Scan() 循环和 bufio.Text() 来获取该行,但缓冲区空间不足。我切换到使用 bufio.ReadLine/ReadString/ReadByte (我尝试了每个)并且每个都有相同的问题。我没有足够的缓冲空间。
我尝试使用 read 并设置缓冲区大小,但正如文档所说,它实际上是一个 const 可以变得更小但永远不会大于 64*1024 字节。然后我尝试使用 File.ReadAt 来设置起始位置,并在我引入每个部分时将其移动,但无济于事。我查看了以下示例和解释(不是详尽的列表):
[将文本文件读入字符串数组(并写入)](https://stackoverflow.com/questions/5884154/golang-read- text-file-into-string-array-and-write) [如何使用 Go 每 10 秒从一个大文件中读取最后](https://stackoverflow.com/questions/17863821/how-to-read-last- lines-from-a-big-file-with-go-every-10-secs) [一行,在 go 中逐行读取文件](https://stackoverflow.com/questions/8757389/reading-file-line-by- line-in-go)
如何将整个文件(逐行或一次整个文件)读入一个切片,以便我可以对这些行执行操作?
这是我尝试过的一些代码:
file, err := os.Open(feedFolder + value) handleError(err) defer file.Close() // fileInfo, _ := file.Stat() var linesInFile []string r := bufio.NewReader(file) for { path, err := r.ReadLine("\n") // 0x0A separator = newline linesInFile = append(linesInFile, path) if err == io.EOF { fmt.Printf("End Of File: %s", err) break } else if err != nil { handleError(err) // if you return error } } fmt.Println("Last Line: ", linesInFile[len(linesInFile)-1])
这是我尝试过的其他东西:
var fileSize int64 = fileInfo.Size() fmt.Printf("File Size: %d\t", fileSize) var bufferSize int64 = 1024 * 60 bytes := make([]byte, bufferSize) var fullFile []byte var start int64 = 0 var interationCounter int64 = 1 var currentErr error = nil for currentErr != io.EOF { _, currentErr = file.ReadAt(bytes, st) fullFile = append(fullFile, bytes...) start = (bufferSize * interationCounter) + 1 interationCounter++ } fmt.Printf("Err: %s\n", currentErr) fmt.Printf("fullFile Size: %s\n", len(fullFile)) fmt.Printf("Start: %d", start) var currentLine []string for _, value := range fullFile { if string(value) != "\n" { currentLine = append(currentLine, string(value)) } else { singleLine := strings.Join(currentLine, "") linesInFile = append(linesInFile, singleLine) currentLine = nil } }
我很茫然。要么我不完全了解缓冲区的工作原理,要么我不了解其他内容。谢谢阅读。
正确答案
bufio.Scan()
并且bufio.Text()
在一个循环中非常适合我处理更大尺寸的文件,所以我想你的行数超过了缓冲区容量。然后
- 检查你的行尾
- 以及您使用哪个 Go 版本
path, err :=r.ReadLine("\n") // 0x0A separator = newline
?看起来有专门针对您的用例的func (b *bufio.Reader) ReadLine() (line []byte, isPrefix bool, err error)
返回值http://golang.org/pkg/bufio/#Reader.ReadLineisPrefix
好了,本文到此结束,带大家了解了《如何读取大型平面文件》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!
-
439 收藏
-
262 收藏
-
193 收藏
-
188 收藏
-
500 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习