【发布时间】:2019-04-11 21:58:17
【问题描述】:
我需要读取一个 CSV 文件并将具有某些值的行的位置记录到一个数组中,然后返回并以没有特定顺序且性能良好的方式检索这些行,因此可以随机访问。
我的程序使用 csv.NewReader(file),但我看不到获取或设置它使用的文件偏移量的方法。我尝试使用 file.Seek(0,io.SeekCurrent) 返回文件位置,但在调用 reader.Read() 之间它不会改变。我还尝试了 fmt.Println("+v +v\n",reader,file) 来查看是否有任何东西存储了阅读器的文件位置,但我没有看到。如果找到文件位置,我也不知道使用文件位置的最佳方法。
这是我需要做的:
file,_ = os.Open("stuff.csv")
reader = csv.NewReader(file)
//read file and record locations
for {
line,_ = reader.Read()
if wantToRememberLocation(line) {
locations = append(locations, getLocation()) //need this function
}
}
//then revisit certain lines
for {
reader.GoToLine(locations[random]) //need this function
line,_ = reader.Read()
doStuff(line)
}
有没有办法用 csv 库做到这一点,还是我必须使用更原始的文件 io 函数编写自己的方法?
【问题讨论】:
-
您确定没有其他方法可以做您想做的事吗?你可以只保存你感兴趣的记录吗?如果您确实需要保存这些行的文件偏移量,您可以通过创建自己的阅读器来包装文件对象来完成这项工作。您可以编写阅读器的
Read方法,使其永远不会超过结尾一通电话。如果您让您的阅读器保存当前行的偏移量并在 CSV 阅读器上执行Read后查看它,我认为这将为您提供正确的偏移量。你必须玩它。 -
XY 问题是询问您尝试的解决方案,而不是您的实际问题:The XY Problem。
-
我正在构建一个工具来有效地处理巨大的 csv 文件并且没有 ram 来保存所有的行,所以我需要保存它们的位置。我正在考虑构建自己的阅读器,但想先看看我是否可以使用现有阅读器进行随机访问。
-
您也许可以在读取文件时记录所有换行位置(例如使用TeeReader),然后将记录编号与换行位置相关联。这仅适用于您的文件不包含 cmets、空行和带换行符的引用值。
-
谢谢彼得,这行得通。使用
io.TeeReader(file,buffer)复制正在读取的行,line,_ = buffer.ReadBytes('\n')获取行,然后使用len(line)获取大小并将其添加到运行总数中以获取位置,但我希望这不会读取 10,000,000 行 CSV 时,速度太慢了。仍然需要找到一种快速返回并将单个行解析为 csv 的方法。