在軟件系統中,IO速度比內存速度慢,IO讀寫在不少狀況下會是系統的瓶頸。java
在java標準IO操做中,InputStream和OutputStream提供基於流的IO操做,以字節爲處理單位;Reader和Writer實現了Buffered緩存,以字符爲處理單位。緩存
從Java1.4開始,增長NIO(New IO),增長緩存Buffer和通道Channel,以塊爲處理單位,是雙向通道(可讀可寫,相似RandomAccessFile),支持鎖和內存映射文件訪問接口,大大提高了IO速度。dom
如下例子簡單測試常見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和內存映射訪問文件,速度最快。測試