大文件定位某一行?

2017-08-22 19:13:37 +08:00
 kaiser1992
现有一个很大的文件(比如 40G 的文本),假如我随机定位某一行,怎么样实现最快(时间和空间)?
希望 V 友们想什么说什么,畅所欲言
8521 次点击
所在节点    程序员
81 条回复
ashfinal
2017-08-22 19:18:29 +08:00
40 G …… 这,这
15015613
2017-08-22 19:20:18 +08:00
查找内容的话,grep
输出特定行,sed
kaiser1992
2017-08-22 19:22:26 +08:00
@15015613 grep 是顺序查找太慢,sed 也需要遍历
Fishdrowned
2017-08-22 19:41:13 +08:00
要是打开没规律的文本文件,你倒是说什么算法不用遍历?判断行数难道不用先知道前面有几行?
jfcherng
2017-08-22 19:42:52 +08:00
https://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html

grep 其實用了很多黑科技的,速度不是一般快。
Fishdrowned
2017-08-22 19:47:20 +08:00
优化方法估计只能多核并行遍历了。如果文件内容不会变化,遍历完之后可以缓存结果
chunk
2017-08-22 19:50:19 +08:00
dd
sofs
2017-08-22 19:51:57 +08:00
40G 的文本我不敢去操作
qian19876025
2017-08-22 20:32:19 +08:00
@Fishdrowned 除非大部分读进内存 不然你没法 并行
sun1991
2017-08-22 20:35:49 +08:00
先扫描一遍, 获取所有行的 pos, 保存起来.
reus
2017-08-22 20:38:33 +08:00
加索引
Fishdrowned
2017-08-22 20:42:04 +08:00
@qian19876025 当然可以并行。按文件大小设置几个断点,然后每个线程从断点处开始遍历,找到换行符就记录一下位置,并不需要多少内存。全部完成后汇总,每一行的位置都出来了
FanWall
2017-08-22 20:47:41 +08:00
@Fishdrowned 最坏的情况缓存大小是文件大小的四倍
Fishdrowned
2017-08-22 20:56:27 +08:00
缓存大不用怕,因为缓存是有组织的,内存不够就放磁盘,快速查找不难实现。
gstqc
2017-08-22 20:58:38 +08:00
只查找少数几次:调用 grep,如果你实现了一个比 grep 更快的算法,那牛逼大了
经常查找:扫一遍,建个索引存下来
lululau
2017-08-22 21:45:53 +08:00
扫描一遍文件,把每一个换行符的索引记录下来,然后 dd 就可以了,不知道 dd 就 man 2 lseek
webster
2017-08-22 21:54:26 +08:00
用 grep 找过 30G 的文件 感觉真的很科技 很快
privil
2017-08-22 22:14:30 +08:00
gouchaoer
2017-08-22 22:23:10 +08:00
ls 的回答都是什么啊,lz 需求是定位某一行
fseek 可以访问文件偏移量,但是行是以换行符确定的,你需要遍历整个文件

要以常数时间定位某一行的话自己建立一个索引就 ok 了,先遍历文件遇到换行符就记录这是第几行,以及当前 fseek 偏移量
kaiser1992
2017-08-22 22:29:33 +08:00
@gstqc 建索引需要时间,存索引需要的空间最后貌似比源文件都大了把

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/384956

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX