本文介绍了不一样的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 的要点: