java IO性能对比----read文件
本次对比内容为:(jdk1.8)
fileInputStream:最基本的文件读取(带自己声明的缓冲区)
dataInputStream:字节读取,在《java编程思想》一书中描述为使用最多的读取文件方式(带自己声明的缓冲区)
bufferedInputStream:带缓冲的读取方式(带自己声明的缓冲区)
dataInputStream(bufferedInputStream):组合后的读取方式(带自己声明的缓冲区)
bufferedReader:字符读取方式
channel:nio中的新的读取方式
map:内存映射文件
(说明:本次对比都有缓存参与,不对比无缓存的情况,因为无缓存情况下的任意方式的读性能远远落后于有缓存的方式,因此不在此对比)
对同一文件的读取:文件为大小为:a)847 MB (888,888,890 字节) b)75.2 MB (78,888,890 字节) c) 6.56 MB (6,888,890 字节) d) 575 KB (588,890 字节)
package javaIO; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * Created by EnjoyD on 2016/12/20. */ public class IO { private static String filepath="." + File.separator +"testIO.txt"; private abstract static class Tester{ private String name; Tester(String name){ this.name=name; } private void runTest(){ try { long start=System.currentTimeMillis(); test(); long offset=System.currentTimeMillis()-start; System.out.println(this.name+":"+offset); }catch (Exception e){ System.err.println("err"); e.printStackTrace(); } } public abstract void test() throws IOException; } private static Tester [] testers={ new Tester("fileInputStream") { @Override public void test() throws IOException { FileInputStream f=new FileInputStream(filepath); { int read; byte []b=new byte[1024]; while((read=f.read(b,0,1024))!=-1) for (int i=0;i<1024;i++) { byte tem = b[i]; } } f.close(); } }, new Tester("dataInputStream") { @Override public void test() throws IOException { DataInputStream d=new DataInputStream(new FileInputStream(filepath)); { int read; byte []b=new byte[1024]; while ((read=d.read(b,0,1024))!=-1) for (int i=0;i<1024;i++) { byte tem = b[i]; } } d.close(); } }, new Tester("bufferedInputStream") { @Override public void test() throws IOException{ BufferedInputStream b=new BufferedInputStream(new FileInputStream(filepath),1024); { int read; byte [] by=new byte[1024]; while((read=b.read(by,0,1024))!=-1) for (int i=0;i<1024;i++) { byte tem = by[i]; } } b.close(); } }, new Tester("datainputStream(buferedinputStream)") { @Override public void test() throws IOException { DataInputStream d=new DataInputStream(new BufferedInputStream(new FileInputStream(filepath),1024)); { int read; byte [] by=new byte[1024]; while((read=d.read(by,0,1024))!=-1) for (int i=0;i<1024;i++) { byte tem = by[i]; } } d.close(); } }, new Tester("bufferedReader") { @Override public void test() throws IOException { Reader f=new BufferedReader(new FileReader(filepath)); { int read; while((read=f.read())!=-1); } f.close(); } }, new Tester("channel") { @Override public void test() throws IOException { FileChannel fc=new FileInputStream(filepath).getChannel(); ByteBuffer buff=ByteBuffer.allocate(1024); while((fc.read(buff)!=-1)){
buff.flip(); while (buff.hasRemaining()){ buff.get(); } buff.clear(); } fc.close(); } }, new Tester("maped") { @Override public void test() throws IOException { FileChannel fc=new RandomAccessFile(filepath,"rw").getChannel(); ByteBuffer buff=fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size()).asReadOnlyBuffer(); while (buff.hasRemaining()) { buff.get(); } fc.close(); } } }; public static void main(String[] args) { for (Tester t :testers){ t.runTest(); } } }
测试1:847 MB (888,888,890 字节) 单位“豪秒”
测试2:75.2 MB (78,888,890 字节) 单位“豪秒”
测试3:6.56 MB (6,888,890 字节) 单位“豪秒”
测试4:575 KB (588,890 字节) 单位“豪秒”
根据这些基本的测试来看,对于大文件读取,在使用了自己声明的1K缓冲区后,前四种方式的读取字节的速度相差不多,并且与最后一种方式----内存映射文件的读取速度相差不多。因此如果需要按字节进行读取,前四种方式皆可,当然如果内存足够大,可以直接使用内存映射文件的方式读取。