java-IO操作性能对比

在软件系统中,IO速度比内存速度慢,IO读写在很多情况下会是系统的瓶颈。

在java标准IO操作中,InputStream和OutputStream提供基于流的IO操作,以字节为处理单位;Reader和Writer实现了Buffered缓存,以字符为处理单位。

从Java1.4开始,增加NIO(New IO),增加缓存Buffer和通道Channel,以块为处理单位,是双向通道(可读可写,类似RandomAccessFile),支持锁和内存映射文件访问接口,大大提升了IO速度。

以下例子简单测试常见IO操作的性能速度。

 

 

[java] view plain copy
 
  1. /** 
  2.  * 测试不同io操作速度 
  3.  *  
  4.  * @author peter_wang 
  5.  * @create-time 2014-6-4 下午12:52:48 
  6.  */  
  7. public class SpeedTest {  
  8.     private static final String INPUT_FILE_PATH = "io_speed.txt";  
  9.     private static final String OUTPUT_FILE_PATH = "io_speed_copy.txt";  
  10.   
  11.     /** 
  12.      * @param args 
  13.      */  
  14.     public static void main(String[] args) {  
  15.         long ioStreamTime1 = ioStreamCopy();  
  16.         System.out.println("io stream copy:" + ioStreamTime1);  
  17.   
  18.         long ioStreamTime2 = bufferedStreamCopy();  
  19.         System.out.println("buffered stream copy:" + ioStreamTime2);  
  20.   
  21.         long ioStreamTime3 = nioStreamCopy();  
  22.         System.out.println("nio stream copy:" + ioStreamTime3);  
  23.           
  24.         long ioStreamTime4 = nioMemoryStreamCopy();  
  25.         System.out.println("nio memory stream copy:" + ioStreamTime4);  
  26.     }  
  27.   
  28.     /** 
  29.      * 普通文件流读写 
  30.      *  
  31.      * @return 操作的时间 
  32.      */  
  33.     private static long ioStreamCopy() {  
  34.         long costTime = -1;  
  35.         FileInputStream is = null;  
  36.         FileOutputStream os = null;  
  37.         try {  
  38.             long startTime = System.currentTimeMillis();  
  39.             is = new FileInputStream(INPUT_FILE_PATH);  
  40.             os = new FileOutputStream(OUTPUT_FILE_PATH);  
  41.             int read = is.read();  
  42.             while (read != -1) {  
  43.                 os.write(read);  
  44.                 read = is.read();  
  45.             }  
  46.             long endTime = System.currentTimeMillis();  
  47.             costTime = endTime - startTime;  
  48.         }  
  49.         catch (FileNotFoundException e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.         catch (IOException e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.         finally {  
  56.             try {  
  57.                 if (is != null) {  
  58.                     is.close();  
  59.                 }  
  60.                 if (os != null) {  
  61.                     os.close();  
  62.                 }  
  63.             }  
  64.             catch (IOException e) {  
  65.                 e.printStackTrace();  
  66.             }  
  67.         }  
  68.         return costTime;  
  69.     }  
  70.   
  71.     /** 
  72.      * 加入缓存的文件流读写, Reader默认实现缓存,只能读取字符文件,无法准确读取字节文件如图片视频等 
  73.      *  
  74.      * @return 操作的时间 
  75.      */  
  76.     private static long bufferedStreamCopy() {  
  77.         long costTime = -1;  
  78.         FileReader reader = null;  
  79.         FileWriter writer = null;  
  80.         try {  
  81.             long startTime = System.currentTimeMillis();  
  82.             reader = new FileReader(INPUT_FILE_PATH);  
  83.             writer = new FileWriter(OUTPUT_FILE_PATH);  
  84.             int read = -1;  
  85.             while ((read = reader.read()) != -1) {  
  86.                 writer.write(read);  
  87.             }  
  88.             writer.flush();  
  89.             long endTime = System.currentTimeMillis();  
  90.             costTime = endTime - startTime;  
  91.         }  
  92.         catch (FileNotFoundException e) {  
  93.             e.printStackTrace();  
  94.         }  
  95.         catch (IOException e) {  
  96.             e.printStackTrace();  
  97.         }  
  98.         finally {  
  99.             try {  
  100.                 if (reader != null) {  
  101.                     reader.close();  
  102.                 }  
  103.                 if (writer != null) {  
  104.                     writer.close();  
  105.                 }  
  106.             }  
  107.             catch (IOException e) {  
  108.                 e.printStackTrace();  
  109.             }  
  110.         }  
  111.         return costTime;  
  112.     }  
  113.   
  114.     /** 
  115.      * nio操作数据流 
  116.      *  
  117.      * @return 操作的时间 
  118.      */  
  119.     private static long nioStreamCopy() {  
  120.         long costTime = -1;  
  121.         FileInputStream is = null;  
  122.         FileOutputStream os = null;  
  123.         FileChannel fi = null;  
  124.         FileChannel fo = null;  
  125.         try {  
  126.             long startTime = System.currentTimeMillis();  
  127.             is = new FileInputStream(INPUT_FILE_PATH);  
  128.             os = new FileOutputStream(OUTPUT_FILE_PATH);  
  129.             fi = is.getChannel();  
  130.             fo = os.getChannel();  
  131.             ByteBuffer buffer = ByteBuffer.allocate(1024);  
  132.             while (true) {  
  133.                 buffer.clear();  
  134.                 int read = fi.read(buffer);  
  135.                 if (read == -1) {  
  136.                     break;  
  137.                 }  
  138.                 buffer.flip();  
  139.                 fo.write(buffer);  
  140.             }  
  141.             long endTime = System.currentTimeMillis();  
  142.             costTime = endTime - startTime;  
  143.         }  
  144.         catch (FileNotFoundException e) {  
  145.             e.printStackTrace();  
  146.         }  
  147.         catch (IOException e) {  
  148.             e.printStackTrace();  
  149.         }  
  150.         finally {  
  151.             try {  
  152.                 if (fi != null) {  
  153.                     fi.close();  
  154.                 }  
  155.                 if (fo != null) {  
  156.                     fo.close();  
  157.                 }  
  158.                 if (is != null) {  
  159.                     is.close();  
  160.                 }  
  161.                 if (os != null) {  
  162.                     os.close();  
  163.                 }  
  164.             }  
  165.             catch (IOException e) {  
  166.                 e.printStackTrace();  
  167.             }  
  168.         }  
  169.         return costTime;  
  170.     }  
  171.   
  172.     /** 
  173.      * nio内存映射操作数据流 
  174.      *  
  175.      * @return 操作的时间 
  176.      */  
  177.     private static long nioMemoryStreamCopy() {  
  178.         long costTime = -1;  
  179.         FileInputStream is = null;  
  180.         //映射文件输出必须用RandomAccessFile  
  181.         RandomAccessFile os = null;  
  182.         FileChannel fi = null;  
  183.         FileChannel fo = null;  
  184.         try {  
  185.             long startTime = System.currentTimeMillis();  
  186.             is = new FileInputStream(INPUT_FILE_PATH);  
  187.             os = new RandomAccessFile(OUTPUT_FILE_PATH, "rw");  
  188.             fi = is.getChannel();  
  189.             fo = os.getChannel();  
  190.             IntBuffer iIb=fi.map(FileChannel.MapMode.READ_ONLY, 0, fi.size()).asIntBuffer();  
  191.             IntBuffer oIb = fo.map(FileChannel.MapMode.READ_WRITE, 0, fo.size()).asIntBuffer();  
  192.             while(iIb.hasRemaining()){  
  193.                 int read = iIb.get();  
  194.                 oIb.put(read);  
  195.             }  
  196.             long endTime = System.currentTimeMillis();  
  197.             costTime = endTime - startTime;  
  198.         }  
  199.         catch (FileNotFoundException e) {  
  200.             e.printStackTrace();  
  201.         }  
  202.         catch (IOException e) {  
  203.             e.printStackTrace();  
  204.         }  
  205.         finally {  
  206.             try {  
  207.                 if (fi != null) {  
  208.                     fi.close();  
  209.                 }  
  210.                 if (fo != null) {  
  211.                     fo.close();  
  212.                 }  
  213.                 if (is != null) {  
  214.                     is.close();  
  215.                 }  
  216.                 if (os != null) {  
  217.                     os.close();  
  218.                 }  
  219.             }  
  220.             catch (IOException e) {  
  221.                 e.printStackTrace();  
  222.             }  
  223.         }  
  224.         return costTime;  
  225.     }  
  226.   
  227. }  

运行结果:

 

 

[java] view plain copy
 
  1. io stream copy:384  
  2. buffered stream copy:125  
  3. nio stream copy:12  
  4. nio memory stream copy:10  


结论分析:

 

最普通的InputStream操作耗时较长,增加了缓存后速度增加了,用了nio和内存映射访问文件,速度最快。

posted @ 2017-11-06 22:19  有梦就能实现  阅读(483)  评论(0编辑  收藏  举报