问题描述
小弟是新到咱们论坛的,听说这里牛人较多,现有个超出小弟能力的问题期待大家给出意见: 读取300多个每个2G的文件,每个文件都是5列N多行,由于需要从中选出某行某列的数,所以需要按行依次扫描,性能很低很低,所以想到了内存文件映射,但是好像内存文件映射没有读行的方法readLine();请大家帮忙分析下,如何能把FileChannel与readLine()结合呢? 所以请大家给小弟指点下迷津!!!严重感谢大家!!!问题补充:哦,我的业务逻辑主要是每个文件的行数都是一样的在30000000行左右,我需要每隔几十行取一次那一行规定列的数据。比如取第1000行,第2000行的数据,每行有五列,中间用空格分隔。
解决方案
内存映射文件用于解决多个进程共享数据,这么大的文件只要在硬盘上,怎么读都是慢。所以建议你用多线程+FileChannel来提高性能,至于readLine的结合,你可以参考 BufferedReader的做法,就是一个装饰模式,可以阅读JDK的源代码,它的注释非常清晰的。其实readLine也是一个byte一个byte的找,只是找到(c == 'n') || (c == 'r')作为一行的结束罢了。所以,如果频繁读取这些文件,则应该建立一个索引,把每个线程读取的position记下来。
解决方案二:
如果你的业务逻辑就如题所说,且不会经常变,那么针对你的文件结构自己建索引,可以做到比数据库快。数据库的优点是“综合效率”高且能够较灵活应付变化,如果追求速度还是要自己去设计算法。
解决方案三:
大文件读取,内存映射肯定是没用的。多线程会更慢。直接导入数据库才是王道。
解决方案四:
不知道你的文件是什么类型的小弟有个愚见,不知道可不可以存成xml形式的之后用xpath检索
解决方案五:
文件这么大,怎么可能一行一行找。。。肯定要索引下。怎么做呢。。。。我想到的办法是放到数据库里去,如果文件不是经常变动的话,可以把他映射到数据库里去,这个动作只要做一次就好了,以后就可以让数据库帮你找了。