机器学习和生物信息学实验室联盟

标题: 关于Java读写文件速度的测试 [打印本页]

作者: hsc    时间: 2012-3-26 18:17
标题: 关于Java读写文件速度的测试
在测试虚拟硬盘的时候,查了一下基本的读取文件的方法,现在将各个方法列举如下,以及测试速度的时间,供大家作为参考,以后如果用到了,可选用合适的读取方式。

1. BufferedReader,BufferedWriter

这一种方法是实验室常用的一种方式,这种方式的好处是可以读取一行,然后针对每一行进行处理,他是构造一个缓冲流,然后进行读写,但是这种方法是相对比较慢的。
参考代码如下:
  1. BufferedReader br = new BufferedReader(new FileReader(args[0]));
  2.                 BufferedWriter bw=new BufferedWriter(new FileWriter(args[1]));
  3.                 String line;
  4.                 while((line=br.readLine())!=null)
  5.                 {
  6.                         bw.write(line);
  7.                 }
  8.                 bw.flush();
  9.                 bw.close();
  10.                 br.close();
复制代码
参数可以自己选用。

2. RandomAccessFile

这一种方法不常用,是随机读取的方式,这种方式比较特殊,他不隶属于InputStream,OutputStream类系,他是直接继承自Object类的。RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream粘起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件,从这一点上看,假如RandomAccessFile继承了DataInputStream,它也许会干得更好。

参考代码如下:
  1. RandomAccessFile read = new RandomAccessFile(args[0],"r");   
  2.         RandomAccessFile writer = new RandomAccessFile(args[1],"rw");   
  3.         byte[] b = new byte[1024*1024];
  4.         int count;
  5.         while((count=read.read(b))!=-1){  
  6.                 //System.out.println(count);
  7.                 if(count!=b.length)
  8.                 {
  9.                         byte[] t=new byte[count];
  10.                         for(int i=0;i<count;++i)
  11.                                 t[i]=b[i];
  12.                         writer.write(t);
  13.                 }
  14.                 else writer.write(b);   
  15.         }   
  16.         writer.close();   
  17.         read.close();
复制代码
参数选择可以根据后边标记读写的进行选择,比如说第二个参数是"r",说明这是一个读文件的,如果是"rw",说明是写文件的。

3. FileInputStream,FileOutputSteam

这是一个最基本的读写文件的方式,这种读写一般是读取一个字节,或者定义长度的字节个数,如果为了节约时间的话,建议用缓冲区读写,这样速度会快一点。

参考代码如下:
  1. InputStream in=new FileInputStream(new File(args[0]));
  2.                 OutputStream out=new FileOutputStream(new File(args[1]));
  3.                 int count;
  4.                 byte[] b=new byte[1024*1024];
  5.                 while((count=in.read(b))!=-1)
  6.                 {
  7.                         if(count!=b.length)
  8.                 {
  9.                         byte[] t=new byte[count];
  10.                         for(int i=0;i<count;++i)
  11.                                 t[i]=b[i];
  12.                         out.write(t);
  13.                 }
  14.                         else out.write(b);
  15.                 }
  16.                 in.close();
  17.                 out.flush();
  18.                 out.close();
复制代码
参数和第一个选择一样。

4. 内存直接映射

这是一个内存直接映射读取的方式,如果文件大小合适,其他读取方式相对于他来说就是浮云啊,等一下我把各个大小的比对时间放上,大家应该可以看出来。但是这有一个限制,就是如果文件太大的话,映射内存会出现问题,要么就是内存不够,或者就是读取很慢,我觉得应该是文件太大,映射内存会出现不够的现象,然后内存会启动换入换出之类的,会浪费时间。但是基本的文件读写,他还是秒杀的。

参考代码如下:
  1. FileChannel read = new RandomAccessFile(args[0],"r").getChannel();   
  2.         FileChannel writer = new RandomAccessFile(args[1],"rw").getChannel();   
  3.         long i = 0;   
  4.         long size = read.size()/30;
  5.         //System.out.println(read.size());
  6.         ByteBuffer bb,cc = null;   
  7.         while(i<read.size()&&(read.size()-i)>size)
  8.         {   
  9.             bb = read.map(FileChannel.MapMode.READ_ONLY, i, size);   
  10.             cc = writer.map(FileChannel.MapMode.READ_WRITE, i, size);   
  11.             cc.put(bb);   
  12.             i+=size;   
  13.             bb.clear();   
  14.             cc.clear();   
  15.         }   
  16.         bb = read.map(FileChannel.MapMode.READ_ONLY, i, read.size()-i);
  17.         cc = writer.map(FileChannel.MapMode.READ_WRITE, i, read.size()-i);
  18.         cc.put(bb);   
  19.         bb.clear();   
  20.         cc.clear();   
  21.         read.close();   
  22.         writer.close();
复制代码
参数同上。

下边我列出以下各个大小文件,各种读取方式所花费的时间,仅作参考。
表格里边我会用Buffer作为BufferedReader的简写,Random作为RandomAccessFile的简写,FileInput作为FileInputStream的简写,Map作为内存直接映射的简写。我给出两次测试结果。

146M文件 第一次测试 第二次测试
Buffer 4.737s 4.581s
Random 0.251s 0.249s
FileInput 0.27s 0.269s
Map 0.102s 0.104s

除了BufferedReader之外,其他的读取时间基本上没有太大区别。

356M文件 第一次测试 第二次测试
Buffer 10.889s 10.71s
Random 0.558s 0.589s
FileInput 0.637s 0.635s
Map 0.125s 0.124s


570M文件 第一次测试 第二次测试
Buffer 17.215s 17.393s
Random 2.756s 2.243s
FileInput 1.924s 1.975s
Map 0.203s 0.197s


712M文件 第一次测试 第二次测试
Buffer 21.852s 23.262s
Random 3.481s 3.529s
FileInput 3.829s 3.42s
Map 0.246s 0.258s


998M文件 第一次测试 第二次测试
Buffer 34.08s 32.437s
Random 21.817s 20.589s
FileInput 9.669s 9.792s
Map 15.481s 16.886s


由以上图表可以看出,在文件大小一般的情况下,随着文件大小的增加,内存映射基本保持在1秒以下,基本0.2s左右,而其他的都会随着文件的增大有明显的变化,这就是内存直接映射秒杀的地方,但是就是文件增加到了998M之后,时间突然之间会增加很大,不知道是不是因为文件太大,以致于内存里边需要执行操作系统提供的一些保护算法而浪费时间了,这个有待考证,也可能是每次运行完之后没有清理内存,导致数据堵塞,因为内存映射方式,java没有提供相应的直接回收MappedByteBuffer区域的方法,这也会导致另外一种异常就是内存不够。

然后我在网上搜了两种解决方式,但是我自己也没有实验出来,代码是执行了,但是不知道从哪里看出他执行前后的区别。这里也把代码放上。

第一种方式:
  1. System.gc();   
  2.          System.runFinalization();   
  3.          try {   
  4.     Thread.sleep(3000);   
  5. } catch (InterruptedException e) {   
  6.       
  7.     e.printStackTrace();   
  8. }  
复制代码
第二种方式:
  1. public static void unmap(final MappedByteBuffer buffer) {   
  2.         if (buffer == null) {   
  3.             return;   
  4.         }   
  5.         AccessController.doPrivileged(new PrivilegedAction<Object>() {   
  6.             public Object run() {   
  7.                 try {   
  8.                     Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);   
  9.                     if (getCleanerMethod != null) {   
  10.                         getCleanerMethod.setAccessible(true);   
  11.                         Object cleaner = getCleanerMethod.invoke(buffer, new Object[0]);   
  12.                         Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);   
  13.                         if (cleanMethod != null) {   
  14.                             cleanMethod.invoke(cleaner, new Object[0]);   
  15.                         }   
  16.                     }   
  17.                 } catch (Exception e) {   
  18.                     e.printStackTrace();   
  19.                 }   
  20.                 return null;   
  21.             }   
  22.    
  23.         });   
  24.     }  
复制代码
但是执行这个之后,会把时间拖慢,也是一个问题,所以这个问题待解决。


上边是我测试了几个方式的读取方式,这样以后实验室的使用读取文件的方式的时候,可以选用最适合的方式,如果时间是最紧要的,那么可以选用内存直接映射,但是这个要保证内存够用,而且文件合适的情况下,至于上边的那个问题,下边我会继续关注,如果谁了解了,欢迎提示~

如果谁熟悉其他的方式的,欢迎跟帖~

作者: xmubingo    时间: 2012-3-26 18:47
本帖最后由 xmubingo 于 2012-3-26 18:53 编辑

,很全面!!

BufferReader是一次性读取一个Buffer size大小到缓冲区。
BufferedReader(Reader r, int size);可以设置缓冲区大小。

你的测试结果是:
对于BufferedReader按一行行读取然后写入。
对于RandomAccessFile是按1024*1024bytes读取然后写入。
由于他们每次读取的大小不一致,因为他们花费的时间理论上本来就不一样。希望能公平测试。

RandomAccessFile也有readLine这个方法,你可以和BufferedReader的readLine方法进行对比,同时对一个大文件进行读一行写一行的测试。看看各自花多少时间。我相信这样的话Buffer的作用就显现出来了。

FileInputStream可以控制文件流的编码格式。这个之前chenwq讨论过。
作者: zouquan    时间: 2012-3-26 19:06
very gooooooooooooooooood
作者: hsc    时间: 2012-3-26 22:01
xmubingo 发表于 2012-3-26 18:47
,很全面!!

BufferReader是一次性读取一个Buffer size大小到缓冲区。

其实我想突出的是那个内存直接映射方式,简直秒杀其他读取方式~
作者: xmubingo    时间: 2012-3-26 22:47
hsc 发表于 2012-3-26 22:01
其实我想突出的是那个内存直接映射方式,简直秒杀其他读取方式~

嗯,速度很快。但是最好能支持按行读取,而且对文件大小有限制。
作者: hsc    时间: 2012-3-26 22:48
xmubingo 发表于 2012-3-26 18:47
,很全面!!

BufferReader是一次性读取一个Buffer size大小到缓冲区。

针对你说的BufferedReader的也可以设置缓冲区长度的读取,我和ReadAccessFile的缓冲区读取进行比较,同样设置1024*1024的,对于380M的文件,RandomAccessFile需要0.6s左右,而BufferedReader需要6s左右,错了大概10倍。

BufferedReader的缓冲区读取代码如下:
  1. BufferedReader br = new BufferedReader(new FileReader(args[0]));
  2.         BufferedWriter bw=new BufferedWriter(new FileWriter(args[1]));
  3.         String line;
  4.         int count;
  5.         char[] buffer=new char[1024*1024];
  6.         while((count=br.read(buffer))!=-1)
  7.         {
  8.                 //System.out.println(count);
  9.                 if(count!=buffer.length)
  10.                 {
  11.                         char[] t=new char[count];
  12.                         for(int i=0;i<count;++i)
  13.                         {
  14.                                 t[i]=buffer[i];
  15.                         }
  16.                         bw.write(t);
  17.                 }
  18.                 else bw.write(buffer);
  19.         }
复制代码
可以看出使用缓冲区会提高速度,但是相对来说还是RandomAccessFile会高一点

380M 第一次 第二次
Buffer 6.14s 6.075
Random 0.571s 0.581s


作者: xmubingo    时间: 2012-3-26 23:20
hsc 发表于 2012-3-26 22:48
针对你说的BufferedReader的也可以设置缓冲区长度的读取,我和ReadAccessFile的缓冲区读取进行比较,同样 ...

嗯!你的实验很有价值!!!对于读较大的内容,ReadAccessFile会快。

我很想知道,如果用两者,每个方法都用readLine读一行,再write一行,那么380M,看看谁花的时间多点?
作者: hsc    时间: 2012-3-27 11:49
xmubingo 发表于 2012-3-26 23:20
嗯!你的实验很有价值!!!对于读较大的内容,ReadAccessFile会快。

我很想知道,如果用两者,每个方 ...

这个还在找方法,因为ReadAccessFile的readline()是读string,但是没有直接写这个,用其他的方式写总是乱码~
作者: xmubingo    时间: 2012-3-27 18:11
hsc 发表于 2012-3-27 11:49
这个还在找方法,因为ReadAccessFile的readline()是读string,但是没有直接写这个,用其他的方式写总是乱 ...

这样啊,是不是编码的问题呢。
http://hi.baidu.com/cpf_51940889 ... 1e3daad1a2d3e6.html
作者: hsc    时间: 2012-3-27 20:32
xmubingo 发表于 2012-3-27 18:11
这样啊,是不是编码的问题呢。
http://hi.baidu.com/cpf_519408891/blog/item/8ffba63de91e3daad1a2d3e6 ...

确实是编码的问题,但是使用重新编码之后,ReadAccessFile读取一行写入一行,380M的文件需要400多秒,而BufferedReader需要六七秒,两者错了差不多十倍,不知道是不是编码的问题呢,还是ReadAccessFile读取行就是比较慢。

参考代码如下:
  1. RandomAccessFile read = new RandomAccessFile(args[0],"r");   
  2.         RandomAccessFile writer = new RandomAccessFile(args[1],"rw");   
  3.         byte[] b = new byte[1024*1024];
  4.         int count;
  5.         String line;
  6.         while((line=read.readLine())!=null)
  7.         {
  8.                 line+="\r\n";
  9.                 writer.writeBytes(new String(line.getBytes(),"gb2312"));
  10.                 //writer.writeBytes(new String("\r\n","gb2312"));
  11.         }
复制代码

作者: xmubingo    时间: 2012-3-27 20:57
本帖最后由 xmubingo 于 2012-3-27 21:05 编辑
hsc 发表于 2012-3-27 20:32
确实是编码的问题,但是使用重新编码之后,ReadAccessFile读取一行写入一行,380M的文件需要400多秒,而B ...


我可以举个例子。
1)A的读取方法:有个缓冲区,缓冲区大小为1000。每次读取数据先判断在不在我的内存缓冲区中,如果不再就再从硬盘连续读取1000.
2)B的读取方法:没有缓冲区,每次都从硬盘直接读取数据。
现在我让A和B读1000大小的内容,分成1000次读,每次读1的大小。

对于A来说,只需要一次访问硬盘,1000次访问内存。
对于B来说,需要1000次访问硬盘。

已知访问一次硬盘的时间是一次访问内存时间的百倍。

这就是本科操作系统课程缓冲区的优势。你可以再做个实验。BufferedReader的缓冲区大小是8K。让两种方法每次读8bytes。这样就没有编码的差别。效果应该也是BufferedReader好。
作者: hsc    时间: 2012-3-28 00:41
xmubingo 发表于 2012-3-27 20:57
我可以举个例子。
1)A的读取方法:有个缓冲区,缓冲区大小为1000。每次读取数据先判断在不在我的内存 ...

No,效果还是RandomAccess好~
作者: xmubingo    时间: 2012-3-28 09:24
本帖最后由 xmubingo 于 2012-3-28 09:25 编辑
hsc 发表于 2012-3-28 00:41
No,效果还是RandomAccess好~


完整代码文件?时间?
作者: hsc    时间: 2012-3-28 12:01
xmubingo 发表于 2012-3-28 09:24
完整代码文件?时间?
  1. BufferedReader br = new BufferedReader(new FileReader(args[0]));
  2.         BufferedWriter bw=new BufferedWriter(new FileWriter(args[1]));
  3.         String line;
  4. //        while((line=br.readLine())!=null)
  5. //        {
  6. //                bw.write(line);
  7. //                bw.newLine();
  8. //        }
  9.         int count;
  10.         char[] buffer=new char[1024*8];
  11.         while((count=br.read(buffer))!=-1)
  12.         {
  13.                 //System.out.println(count);
  14.                 if(count!=buffer.length)
  15.                 {
  16.                         char[] t=new char[count];
  17.                         for(int i=0;i<count;++i)
  18.                         {
  19.                                 t[i]=buffer[i];
  20.                         }
  21.                         bw.write(t);
  22.                 }
  23.                 else bw.write(buffer);
  24.         }
  25.         bw.flush();
  26.         bw.close();
  27.         br.close();/**/
复制代码
第一次:6.155s
第二次:5.843s
  1. RandomAccessFile read = new RandomAccessFile(args[0],"r");   
  2.         RandomAccessFile writer = new RandomAccessFile(args[1],"rw");   
  3.         byte[] b = new byte[1024*8];
  4.         int count;
  5. //        String line;
  6. //        while((line=read.readLine())!=null)
  7. //        {
  8. //                line+="\r\n";
  9. //                writer.writeBytes(new String(line.getBytes(),"GBK"));
  10. //                //writer.writeBytes(new String("\r\n","gb2312"));
  11. //        }
  12.         while((count=read.read(b))!=-1)
  13.         {  
  14.                 //System.out.println(count);
  15.                 if(count!=b.length)
  16.                 {
  17.                         byte[] t=new byte[count];
  18.                         for(int i=0;i<count;++i)
  19.                                 t[i]=b[i];
  20.                         writer.write(t);
  21.                 }
  22.                 else writer.write(b);   
  23.         }  
  24.         writer.close();   
  25.         read.close();/**/
复制代码
第一次:0.486s
第二次:0.495s

如果说char类型的是双字节的话,我设置成1024*4时间不变
作者: xmubingo    时间: 2012-3-28 13:23
本帖最后由 xmubingo 于 2012-3-28 13:55 编辑
hsc 发表于 2012-3-28 12:01
第一次:6.155s
第二次:5.843s第一次:0.486s
第二次:0.495s


晕!

BufferedReader是自带缓冲区的,可以通过参数设置缓冲区的大小,BufferedReader(Reader, int size),你把它设置成8*1024bytes.

而RandomAccessFile是不带缓冲区的。

你就每次
while(没有读完){
读8bytes数据
写8bytes数据


每次读的是8bytes不是8*1024bytes也不是8*1024char.

你现在每次读的是8KB,相当于BufferedReader没有发挥缓冲区的价值,反而还要浪费时间在填充缓冲区上,当然时间多了。

读1275KB的文件效果!
  1. package test;
  2. import java.io.*;
  3. public class testforbuffer {
  4.         public static void main(String[] args) throws Exception
  5.         {
  6.         BufferedReader br = new BufferedReader(new FileReader("c:\\testin.txt"),8*1024);//缓冲区大小8*1024byte
  7.         BufferedWriter bw=new BufferedWriter(new FileWriter("c:\\testout.txt"));
  8.         int count;
  9.         char[] buffer=new char[4];//用char读8byte
  10.         Long startTime = System.currentTimeMillis();
  11.         while((count=br.read(buffer))!=-1)
  12.         {
  13.                 //System.out.println(count);
  14.                 if(count!=buffer.length)
  15.                 {
  16.                         char[] t=new char[count];
  17.                         for(int i=0;i<count;++i)
  18.                         {
  19.                                 t[i]=buffer[i];
  20.                         }
  21.                         bw.write(t);
  22.                 }
  23.                 else bw.write(buffer);
  24.         }
  25.         bw.flush();
  26.         bw.close();
  27.         br.close();
  28.         Long endTime = System.currentTimeMillis();
  29.         System.out.println("Totle time is "+ (endTime - startTime) + "milliseconds");
  30.         
  31.         //////////////////////////////////////////////////////////////
  32.         
  33.         RandomAccessFile read = new RandomAccessFile("c:\\testin.txt","r");   
  34.         RandomAccessFile writer = new RandomAccessFile("c:\\testout.txt","rw");   
  35.         byte[] b = new byte[8];//读8byte

  36.         startTime = System.currentTimeMillis();
  37.         while((count=read.read(b))!=-1)
  38.         {  
  39.                 //System.out.println(count);
  40.                 if(count!=b.length)
  41.                 {
  42.                         byte[] t=new byte[count];
  43.                         for(int i=0;i<count;++i)
  44.                                 t[i]=b[i];
  45.                         writer.write(t);
  46.                 }
  47.                 else writer.write(b);   
  48.         }
  49.         writer.close();   
  50.         read.close();
  51.         endTime = System.currentTimeMillis();
  52.         System.out.println("Totle time is "+ (endTime - startTime) + "milliseconds");
  53.         }
  54. }
复制代码
输出:
Totle time is 43milliseconds
Totle time is 871milliseconds


BufferedReader只要43毫秒。RandomAccessFile要871毫秒。

缓冲区就是这个作用啊!当你读的东西比较小,比如读一行的时候,我就不需要再向硬盘要数据,而是向内存直接取。这就是为什么我们实验室要用BufferedReader,因为我们都是处理一行行。苍天啊...还要我怎么解释。

作者: hsc    时间: 2012-3-28 17:44
xmubingo 发表于 2012-3-28 13:23
晕!

BufferedReader是自带缓冲区的,可以通过参数设置缓冲区的大小,BufferedReader(Reader, int s ...

哦,你说是八个字节是吧,我看成8K了,不过一般来说8个字节的缓冲区太小了,读起来会很慢,尽管在同一级别上比较,这个是快了点,但是用我设置的那个缓冲区长度,读380M的文件也只需要0.5s左右,在时间作为第一要素的选择上,感觉还是这样的比较好一点,不过当然了,每一种方式都有他的优点和缺点,针对特殊情况选择合适的读取方式才是王道~
作者: xmubingo    时间: 2012-3-28 19:00
本帖最后由 xmubingo 于 2012-3-28 19:28 编辑
hsc 发表于 2012-3-28 17:44
哦,你说是八个字节是吧,我看成8K了,不过一般来说8个字节的缓冲区太小了,读起来会很慢,尽管在同一级别 ...


晕死。我这里根本没有什么八字节的缓冲区。缓冲区大小是8*1024,在定义BufferedReader的时候就设定了!我这里是任务每次要读8个字节的数据。那程序里边的buffer根本就不是缓冲区,是你定义的用来存放取出来的8字节内容啊。
你看好下面的程序我把buffer改成fuck,fuck指代你每次要读取数据的长度
  1. package test;
  2. import java.io.*;
  3. public class testforbuffer {
  4.         public static void main(String[] args) throws Exception
  5.         {
  6.         BufferedReader br = new BufferedReader(new FileReader("c:\\testin.txt"),8*1024);//缓冲区大小8*1024byte
  7.         BufferedWriter bw=new BufferedWriter(new FileWriter("c:\\testout.txt"));
  8.         int count;
  9.         char[] fuck=new char[4];//用char读8byte
  10.         Long startTime = System.currentTimeMillis();
  11.         while((count=br.read(fuck))!=-1)
  12.         {
  13.                 //System.out.println(count);
  14.                 if(count!=fuck.length)
  15.                 {
  16.                         char[] t=new char[count];
  17.                         for(int i=0;i<count;++i)
  18.                         {
  19.                                 t[i]=fuck[i];
  20.                         }
  21.                         bw.write(t);
  22.                 }
  23.                 else bw.write(fuck);
  24.         }
  25.         bw.flush();
  26.         bw.close();
  27.         br.close();
  28.         Long endTime = System.currentTimeMillis();
  29.         System.out.println("Totle time is "+ (endTime - startTime) + "milliseconds");
  30.         
  31.         //////////////////////////////////////////////////////////////
  32.         
  33.         RandomAccessFile read = new RandomAccessFile("c:\\testin.txt","r");   
  34.         RandomAccessFile writer = new RandomAccessFile("c:\\testout.txt","rw");   
  35.         byte[] b = new byte[8];//读8byte

  36.         startTime = System.currentTimeMillis();
  37.         while((count=read.read(b))!=-1)
  38.         {  
  39.                 //System.out.println(count);
  40.                 if(count!=b.length)
  41.                 {
  42.                         byte[] t=new byte[count];
  43.                         for(int i=0;i<count;++i)
  44.                                 t[i]=b[i];
  45.                         writer.write(t);
  46.                 }
  47.                 else writer.write(b);   
  48.         }
  49.         writer.close();   
  50.         read.close();
  51.         endTime = System.currentTimeMillis();
  52.         System.out.println("Totle time is "+ (endTime - startTime) + "milliseconds");
  53.         }
  54. }
复制代码
你可以把成BufferedReader的缓冲区设置成8M。然后每次读8k的数据,依然并且肯定是BufferedReader快!

只要你告诉我每次要读取的数据大小s,我把缓冲区设置成s的倍数。永远都是BufferedReader快!
作者: hsc    时间: 2012-3-28 21:36
xmubingo 发表于 2012-3-28 19:00
晕死。我这里根本没有什么八字节的缓冲区。缓冲区大小是8*1024,在定义BufferedReader的时候就设定了!我 ...

好吧,其实我没有跟你争论什么,刚开始的我只是偶然之间测试了一下速度而已,仅供参考而已,你说的这一点,我确实没有考虑到,每一种方法都有他的优点和缺点,我们取长补短就好了
作者: xmubingo    时间: 2012-3-28 22:17
本帖最后由 xmubingo 于 2012-3-28 22:21 编辑
hsc 发表于 2012-3-28 21:36
好吧,其实我没有跟你争论什么,刚开始的我只是偶然之间测试了一下速度而已,仅供参考而已,你说的 ...


CSDN上的解答比我的回复更加尖锐。很少人愿意给你贴完整代码或者debug。
这是个很简单的缓冲区问题。你说得对,每种方法都有优势。
RandomAccessFile能很快的把整个文件取出来中,抛出去。
在网络应用中,他可以很快速的读取特定字节的内容送出去。
它还有seek,在网络传输的断点续传中,快速偏移的地址,然后读取数据。这些都是“随机访问”的优点。
当然网络传输一般同时需要大缓冲区的支持。
包括map法,它在内存允许范围内存取速度比谁都快。

我们不是在争论,这些细节问题一定要描述清楚,不然下次用到依然要百度google。
作者: hsc    时间: 2012-3-28 23:33
xmubingo 发表于 2012-3-28 22:17
CSDN上的解答比我的回复更加尖锐。很少人愿意给你贴完整代码或者debug。
这是个很简单的缓冲区问题。你 ...

嗯,确实是,我相信以后大家在选用读取方式的时候,会有一个比较清晰的认识了,其实刚开始的时候我对他们的分类也都还不是很清楚,所以拿来做比较的时候就有点鲁莽了,学习了!




欢迎光临 机器学习和生物信息学实验室联盟 (http://123.57.240.48/) Powered by Discuz! X3.2