本次对比内容为:(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 字节)
packagejavaIO;import java.io.*;importjava.nio.ByteBuffer;importjava.nio.channels.FileChannel;/*** Created by EnjoyD on 2016/12/20.*/
public classIO {private static String filepath="." + File.separator +"testIO.txt";private abstract static classTester{privateString name;
Tester(String name){this.name=name;
}private voidrunTest(){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() throwsIOException;
}private static Tester [] testers={new Tester("fileInputStream") {
@Overridepublic void test() throwsIOException {
FileInputStream f=newFileInputStream(filepath);
{intread;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") {
@Overridepublic void test() throwsIOException {
DataInputStream d=new DataInputStream(newFileInputStream(filepath));
{intread;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") {
@Overridepublic void test() throwsIOException{
BufferedInputStream b=new BufferedInputStream(new FileInputStream(filepath),1024);
{intread;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)") {
@Overridepublic void test() throwsIOException {
DataInputStream d=new DataInputStream(new BufferedInputStream(new FileInputStream(filepath),1024));
{intread;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") {
@Overridepublic void test() throwsIOException {
Reader f=new BufferedReader(newFileReader(filepath));
{intread;while((read=f.read())!=-1);
}
f.close();
}
},new Tester("channel") {
@Overridepublic void test() throwsIOException {
FileChannel fc=newFileInputStream(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") {
@Overridepublic void test() throwsIOException {
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 voidmain(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缓冲区后,前四种方式的读取字节的速度相差不多,并且与最后一种方式----内存映射文件的读取速度相差不多。因此如果需要按字节进行读取,前四种方式皆可,当然如果内存足够大,可以直接使用内存映射文件的方式读取。