日期:2014-05-20  浏览次数:20707 次

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

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

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


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

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

------解决方案--------------------
为什么要都读到内存中?
------解决方案--------------------
所谓的一行就是以'\r' '\n'(或者只是'\n')结尾的字节序,如果字符串类 不好处理,试试字节吧。
------解决方案--------------------
做个缓存把数据都缓存到一个map里面,所有用户都访问一个map比较好点,
如果每个用户访问都读文件,并发量大也吃不消
------解决方案--------------------
引用
LZ那种方式做的话。。那还不如直接使用RandomAccessFile随机取行(因为你的数据每行就是一个数字)。。。避免对100w数据的读入与取出list以及截取操作。。虽然RandomAccessFile在100w中随机读取行,速度是比较慢的,但是肯定比你那种方式快。。。


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

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

------解决方案--------------------
探讨

忘了说一点,抽奖的结果会有15万以上的数据,funfenffun和ghsau的方法不管哪种,都会不停的去遍历文件,耗时过长。两种方法我已经试过了,均超过了10分钟,weblogic超时停止了。而且,10分钟也太长了点,最好能在2分钟内搞定。
RandomAccessFile的问题:seek每次定位其实都是遍历一次文件,不过效率要比funfenffun的那种快一些而已。