+ -
当前位置:首页 → 问答吧 → 大文件随机读取问题

大文件随机读取问题

时间:2011-12-09

来源:互联网

现在有一个100万行的信息的文件,要进行抽奖。随机取出一定量的信息。问下各位怎样做最快最优呢?

先说我的做法:
1.通过bufferreader按行读取
2.存入一个stringbuffer中,结束后,再split(",")存入一个string数组a中。
3.通过a.length得出数据量总数(比如num=100万)。
4.进行ran.nextInt(num)取得中奖信息的下标,存入list中。
5.a[list.get(i)],得到抽奖结果。

这有个弊端,如果多人同时操作的话,服务器照样卡死。
这是我所能做的最大的优化了,不知各位还能否有更好的方法。

作者: lk0328   发布时间: 2011-12-09

lz不用把所有数据都取出来,
先计算出总行数 
取随机数
然后取出这一行
就行了

作者: funfenffun   发布时间: 2011-12-09

引用 1 楼 funfenffun 的回复:

lz不用把所有数据都取出来,
先计算出总行数
取随机数
然后取出这一行
就行了

这个我想过,但是没有取随机一行的方法啊。

作者: lk0328   发布时间: 2011-12-09

100万行,没行的数据长度是一样的吗?

作者: ghsau   发布时间: 2011-12-09

引用 3 楼 ghsau 的回复:

100万行,没行的数据长度是一样的吗?

对,可以暂时考虑一行一条信息类似
1,
2,
3,
这样

作者: lk0328   发布时间: 2011-12-09

用RandomAccessFile,里面有seek方法,是偏移量,再读取的话,是从偏移位置开始读取。
如果每行数据长度一样的话,就好办了,直接偏移随机数*长度,然后读取一行数据。
如果每行数据长度不一样,就需要你程序控制了。
流的话,也有skip方法。

作者: ghsau   发布时间: 2011-12-09

我觉得lz卡死主要出在StringBuffer上面,1000000行*每行50字符好了,放到StringBuffer里面,能把heap给爆了
lz不想大改的话,这样改
取行数 while((line = reader.readLine())!=null){ count++; }
取随机数ran
跳过ran行,取一行 for(int i=0;i<ran;i++){ reader.readLine(); } line = reader.readLine();

至少内存不会爆

作者: funfenffun   发布时间: 2011-12-09

引用 6 楼 funfenffun 的回复:

我觉得lz卡死主要出在StringBuffer上面,1000000行*每行50字符好了,放到StringBuffer里面,能把heap给爆了
lz不想大改的话,这样改
取行数 while((line = reader.readLine())!=null){ count++; }
取随机数ran
跳过ran行,取一行 for(int i=0;i<ran;i++){ reader.rea……

没说清楚,是 StringBuffer.toString().split(",")的时候heap用得超多,会爆的

作者: funfenffun   发布时间: 2011-12-09

引用 6 楼 funfenffun 的回复:

我觉得lz卡死主要出在StringBuffer上面,1000000行*每行50字符好了,放到StringBuffer里面,能把heap给爆了
lz不想大改的话,这样改
取行数 while((line = reader.readLine())!=null){ count++; }
取随机数ran
跳过ran行,取一行 for(int i=0;i<ran;i++){ reader.rea……

跳过ran行?跳过ran行可以直接读了

作者: ghsau   发布时间: 2011-12-09

引用 4 楼 lk0328 的回复:

引用 3 楼 ghsau 的回复:

100万行,没行的数据长度是一样的吗?

对,可以暂时考虑一行一条信息类似
1,
2,
3,
这样


一条一行,共100W行。
不都有了?还要啥?还是说100W行只是比如?

作者: lxwankkk   发布时间: 2011-12-09

引用 8 楼 ghsau 的回复:
跳过ran行?跳过ran行可以直接读了

不能么?
ran.nextInt(num) 存入list中。
a[list.get(i)] 得到结果
不就是找第ran行么

反正先把空间爆了的问题解决了,时间的问题再说,这个优化有必要好好写的,改进的空间很大丫

作者: funfenffun   发布时间: 2011-12-09

为什么要都读到内存中?

作者: gukuitian   发布时间: 2011-12-09

所谓的一行就是以'\r' '\n'(或者只是'\n')结尾的字节序,如果字符串类 不好处理,试试字节吧。

作者: AFer198215   发布时间: 2011-12-09

做个缓存把数据都缓存到一个map里面,所有用户都访问一个map比较好点,
如果每个用户访问都读文件,并发量大也吃不消

作者: likgui   发布时间: 2011-12-09

引用
LZ那种方式做的话。。那还不如直接使用RandomAccessFile随机取行(因为你的数据每行就是一个数字)。。。避免对100w数据的读入与取出list以及截取操作。。虽然RandomAccessFile在100w中随机读取行,速度是比较慢的,但是肯定比你那种方式快。。。


1. list的get(i)方法从100w中取随机数据的速度明显不高。。
2. 读取100w也慢。。stringbuffer很容易就溢出了。。至少也得用到缓冲流根据字节数组的方式读比较快。。或者可以用内存映射应该是很快的了。。。

可以的话。。明天我做一下测试。。根据测试结果定。。。

作者: kouyiSC   发布时间: 2011-12-09

热门下载

更多