本文介紹了不一樣的IO方式以及他們之間的效率比較java
1.一次讀取寫入單個字節(讀取400M的文件浪費了好久,等了好久沒讀取完成,證實其效率不好)數組
1 public class CopyFileDemo { 2 public static void main(String[] args) throws IOException { 3 FileInputStream fis = new FileInputStream("a.txt"); 4 FileOutputStream fos = new FileOutputStream("b.txt"); 5 6 // 方式一:一次讀取寫入單個字節 7 int i = 0; 8 while ((i = fis.read()) != -1) { 9 fos.write(i); 10 } 11 fos.close(); 12 fis.close(); 13 } 14 }
2.一次讀取寫入多個字節(讀取400M的文件700ms)app
1 public class CopyFileDemo { 2 public static void main(String[] args) throws IOException { 3 FileInputStream fis = new FileInputStream("a.txt"); 4 FileOutputStream fos = new FileOutputStream("b.txt"); 5 // 方式二:一次讀取寫入一個字節數組 6 byte[] by = new byte[1024]; 7 int len = 0; 8 while ((len = fis.read(by)) != -1) { 9 fos.write(by, 0, len); 10 } 11 fos.close(); 12 fis.close(); 13 } 14 }
3.文件流輸入輸出(讀取400M的文件5000ms,爲何更慢呢,猜想是readline這裏,大神能夠指出來)性能
1 public class CopyFileDemo3 { 2 public static void main(String[] args) throws IOException { 3 BufferedReader br=new BufferedReader(new FileReader("a.txt")); 4 //若是d文件中有數據,true表示繼續往文件中追加數據 5 BufferedWriter bw=new BufferedWriter(new FileWriter("d.txt",true)); 6 7 String line=null; 8 //高效字符輸入流的特有方法readline(),每次讀取一行數據 9 while((line=br.readLine())!=null){ 10 bw.write(line); 11 //高效字符輸出流的特有方法newline() 12 bw.newLine(); 13 //將緩衝區中的數據刷到目的地文件中 14 bw.flush(); 15 } 16 //關閉流,其實關閉的就是java調用的系統底層資源。在關閉前,會先刷新該流。 17 bw.close(); 18 br.close(); 19 } 20 }
BufferedInputStream 會根據狀況自動爲咱們預讀更多的字節數據到它本身維護的一個內部字節數組緩衝區中,這樣咱們即可以減小系統調用次數,從而達到其緩衝區的目的。因此要明確的一點是 BufferedInputStream 的做用不是減小 磁盤IO操做次數(這個OS已經幫咱們作了),而是經過減小系統調用次數來提升性能的。spa
4.NIO讀取 (400M的視頻文件,讀取要長達700ms)操作系統
1 public class ReadDemo{ 2 public static void main(String[] args) throws IOException { 3 File file = new File("sdtgj.mp4"); 4 FileInputStream in = new FileInputStream(file); 5 FileChannel channel = in.getChannel(); 6 ByteBuffer buff = ByteBuffer.allocate(1024); 7 8 long begin = System.currentTimeMillis(); 9 while (channel.read(buff) != -1) { 10 buff.flip(); 11 buff.clear(); 12 } 13 long end = System.currentTimeMillis(); 14 System.out.println("time is:" + (end - begin)+"毫秒 "+"讀取 "+file.getName()); 15 } 16 }
5.內存映射讀取 (400M的視頻文件,讀取只要100ms)code
1 public class ReadDemo{ 2 3 static final int BUFFER_SIZE = 1024; 4 5 public static void main(String[] args) throws Exception { 6 7 File file = new File("sdtgj.mp4"); 8 FileInputStream in = new FileInputStream(file); 9 FileChannel channel = in.getChannel(); 10 MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 0, 11 channel.size()); 12 13 byte[] b = new byte[1024]; 14 int len = (int) file.length(); 15 16 long begin = System.currentTimeMillis(); 17 18 for (int offset = 0; offset < len; offset += 1024) { 19 20 if (len - offset > BUFFER_SIZE) { 21 buff.get(b); 22 } else { 23 buff.get(new byte[len - offset]); 24 } 25 } 26 27 long end = System.currentTimeMillis(); 28 System.out.println("time is:" + (end - begin)+"毫秒 "+"讀取 "+file.getName()); 29 30 } 31 }
MappedByteBuffer 不受JVM堆大小控制,速度最快。
MappedByteBuffer 的要點: