Java-IO操作性能对比

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

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

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

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

  1 import java.io.*;
  2 import java.nio.ByteBuffer;
  3 import java.nio.IntBuffer;
  4 import java.nio.channels.FileChannel;
  5 
  6 /**
  7  * Created by yubo10581 on 2016/1/28.
  8  */
  9 public class fileSpeedTest {
 10     private static final String INPUT_FILE_PATH = "E:/IdeaProjects/theFirstProject/testOne/testFile/io_speed.txt";
 11     private static final String OUTPUT_FILE_PATH = "E:/IdeaProjects/theFirstProject/testOne/testFile/io_speed_copy.txt";
 12 
 13     public static void main(String[] args) {
 14         long ioStreamCopyTime = ioStreamCopy();
 15         System.out.println("io stream copy:" + ioStreamCopyTime+"ms");
 16 
 17         long bufferedStreamTime = bufferedStreamCopy();
 18         System.out.println("buffered stream copy:" + bufferedStreamTime+"ms");
 19 
 20         long nioStreamTime = nioStreamCopy();
 21         System.out.println("nio stream copy:" + nioStreamTime+"ms");
 22 
 23         long nioMemoryStreamTime = nioMemoryStreamCopy();
 24         System.out.println("nio memory stream copy:" + nioMemoryStreamTime+"ms");
 25 
 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         } catch (FileNotFoundException e) {
199             e.printStackTrace();
200         } catch (IOException e) {
201             e.printStackTrace();
202         } finally {
203             try {
204                 if (fi != null) {
205                     fi.close();
206                 }
207                 if (fo != null) {
208                     fo.close();
209                 }
210                 if (is != null) {
211                     is.close();
212                 }
213                 if (os != null) {
214                     os.close();
215                 }
216             } catch (IOException e) {
217                 e.printStackTrace();
218             }
219         }
220         return costTime;
221     }
222 
223 }

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

原文地址:https://www.cnblogs.com/Lightning-Kid/p/5166116.html