现在有一个100万行的信息的文件,要进行抽奖。随机取出一定量的信息。问下各位怎样做最快最优呢?先说我的做法:
1.通过bufferreader按行读取
2.存入一个stringbuffer中,结束后,再split(",")存入一个string数组a中。
3.通过a.length得出数据量总数(比如num=100万)。
4.进行ran.nextInt(num)取得中奖信息的下标,存入list中。
5.a[list.get(i)],得到抽奖结果。这有个弊端,如果多人同时操作的话,服务器照样卡死。
这是我所能做的最大的优化了,不知各位还能否有更好的方法。
1.通过bufferreader按行读取
2.存入一个stringbuffer中,结束后,再split(",")存入一个string数组a中。
3.通过a.length得出数据量总数(比如num=100万)。
4.进行ran.nextInt(num)取得中奖信息的下标,存入list中。
5.a[list.get(i)],得到抽奖结果。这有个弊端,如果多人同时操作的话,服务器照样卡死。
这是我所能做的最大的优化了,不知各位还能否有更好的方法。
如果每行数据长度一样的话,就好办了,直接偏移随机数*长度,然后读取一行数据。
如果每行数据长度不一样,就需要你程序控制了。
流的话,也有skip方法。
lz不想大改的话,这样改
取行数 while((line = reader.readLine())!=null){ count++; }
取随机数ran
跳过ran行,取一行 for(int i=0;i<ran;i++){ reader.readLine(); } line = reader.readLine();至少内存不会爆
ran.nextInt(num) 存入list中。
a[list.get(i)] 得到结果
不就是找第ran行么反正先把空间爆了的问题解决了,时间的问题再说,这个优化有必要好好写的,改进的空间很大丫
如果每个用户访问都读文件,并发量大也吃不消
RandomAccessFile的问题:seek每次定位其实都是遍历一次文件,不过效率要比funfenffun的那种快一些而已。
public class BigFileRead {
public static void main(String[] args){
t2();
// t1();
}
//随机读取
static void t2(){
File fd = new File("e:\\test\\fd.dt");
File fi = new File("e:\\test\\fi.dt");
RandomAccessFile fdIn = null;
RandomAccessFile fiIn = null;
byte[] buffer = new byte[512];
long post = 0;
int ri = 0;
int dataLen = 0;
long dataPost = 0;
int readLen = 0;
long a = 0;
try{
fdIn = new RandomAccessFile(fd,"r");
fiIn = new RandomAccessFile(fi,"r");
a = System.currentTimeMillis();
for(int i=0;i<15*100*100;i++){
for(;;){
ri = (int) (Math.random()*100*100*100);
if(ri<0 || ri>100*100*100){
continue;
}else{
break;
}
}
post = ri*12;
fiIn.seek(post);
fiIn.read(buffer,0,12);
dataPost = Utility.byte2Long(buffer, 0);
dataLen = Utility.byte2Int(buffer,8);
fdIn.seek(dataPost);
readLen = fdIn.read(buffer, 0, dataLen);
if(0 < readLen){
System.out.println(i+":"+( new String(buffer, 0, readLen)));
}
}
System.out.println("耗时:" + (System.currentTimeMillis()-a));
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
if(null != fdIn) fdIn.close();
}catch(Exception ex){
}
try{
if(null != fiIn) fiIn.close();
}catch(Exception ex){
}
}
}
//创建文件
static void t1(){
File fd = new File("e:\\test\\fd.dt");//数据文件
File fi = new File("e:\\test\\fi.dt");//索引
FileOutputStream fdOut = null;
FileOutputStream fiOut = null;
byte[] buffer = null;
long offset=0;
int len = 0;
try{
fdOut = new FileOutputStream(fd);
fiOut = new FileOutputStream(fi);
for(int i=0,end=100*100*100;i<end;i++){
buffer = ("<<_"+i+"_>>").getBytes();
fdOut.write(buffer);
len = buffer.length;
offset += len;
fiOut.write(Utility.long2Byte(offset));
fiOut.write(Utility.int2Byte(len));
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
if(null != fdOut) fdOut.close();
}catch(Exception ex){
}
try{
if(null != fiOut) fiOut.close();
}catch(Exception ex){
}
}
}
}
首先生成100w以内的15w个随机数字,然后将其排序(存入a数组中),接着开始遍历这个文件,读一行,i++,然后当i=a[j]的时候,读取这行信息进行下面的操作,接着j++,当j>15W的时候,退出遍历。这样只需要一次遍历就取出了所有随机的数据。