
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
昆明IT培训的老师这一期给大家讲Java--Stream,NIO ByteBuffer,NIO MappedByteBuffer性能对比。
目前Java中最IO有多种文件读取的方法,本文章对比Stream,NIO ByteBuffer,NIO MappedByteBuffer的性能,让我们知道到底怎么能写出性能高的文件读取代码。
package com.seeyon.nio;
import org.junit.Test;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/**
* Created by yangyu on 16/12/28.
*/
/**
*比较Stream流,NIO ByteBuffer,NIO MappedByteBuffer性能对比
*其中Stream最慢,NIO MappedByteBuffer最快
* Stream:1000ms
* NIO ByteBuffer:220ms
* NIO MappedByteBuffer:112ms
*/
public class Compare {
/**
*使用stream作为IO流读取和写入文件
*速度:1000ms左右
*
* @throws IOException
*/
@Test
public void useStream() throws IOException {
long startTime = System.currentTimeMillis();
/**
* 4000000个整数长度的文件
*/
int num = 2000 * 2000;
/**
*带缓冲的输出流,写文件
*/
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("/Users/yangyu/Downloads/compare.tmp")));
for (int i = 0; i < num; i++) {
dataOutputStream.writeInt(i);
}
dataOutputStream.close();
int data = 0;
/**
*带缓冲的输入流,读文件
*/
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("/Users/yangyu/Downloads/compare.tmp")));
try {
while (true) {
data = in.readInt();
}
} catch (EOFException e) {
System.out.println("读取完成"+data);
}
in.close();
long endTime = System.currentTimeMillis();
System.out.println("ms:" + (endTime - startTime));
}
/**
*使用NIO ByteBuffer
*时间:220ms
* @throws IOException
*/
@Test
public void useNioByteBuffer() throws IOException {
long startTime = System.currentTimeMillis();
int num = 2000*2000;
/**
*文件输出流
*/
FileOutputStream fileOutputStream = new FileOutputStream("/Users/yangyu/Downloads/compare.tmp");
/**
* NIO Channel通道
*/
FileChannel fileChannel = fileOutputStream.getChannel();
/**
* ByteBuffer缓冲区
*/
ByteBuffer buffer = ByteBuffer.allocate(num*5);
for (int i = 0; i < num; i++) {
buffer.putInt(i);
}
/**
*为写做准备
*/
buffer.flip();
/**
*写操作
*/
fileChannel.write(buffer);
fileChannel.close();
/**
*缓冲区
*/
ByteBuffer buffer1 = ByteBuffer.allocate(num*5);
/**
*文件输入流
*/
FileInputStream in = new FileInputStream("/Users/yangyu/Downloads/compare.tmp");
/**
*输入通道
*/
FileChannel fin = in.getChannel();
/**
*为读取做准备
*/
buffer1.clear();
System.out.println(buffer1.limit());
/**
*读取
*/
fin.read(buffer1);
fin.close();
long endTime = System.currentTimeMillis();
System.out.println("ms:" + (endTime - startTime));
buffer1.flip();
System.out.println(buffer1.limit());
}
/**
*使用MappedByteBuffer,通过FileChannel将文件映射到内存
*时间:112ms
* @throws IOException
*/
@Test
public void useRandomAccess() throws IOException {
long startTime = System.currentTimeMillis();
int num = 2000*2000;
/**
*使用可随机访问位置的RandomAccessFile
*/
RandomAccessFile file = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
/**
*获取通道Channel
*/
FileChannel fileChannel = file.getChannel();
/**
*将文件映射到缓冲区MappedByteBuffer
*/
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,num*4);
/**
*写文件
*/
for (int i = 0; i < num; i++) {
mappedByteBuffer.putInt(i);
}
fileChannel.close();
int data=0;
RandomAccessFile file1 = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
FileChannel fc = file1.getChannel();
MappedByteBuffer mappedByteBuffer1 = fc.map(FileChannel.MapMode.READ_WRITE,0,file1.length());
/**
*读文件
*/
while (mappedByteBuffer1.hasRemaining()){
data = mappedByteBuffer1.getInt();
}
fc.close();
long endTime = System.currentTimeMillis();
System.out.println("ms:" + (endTime - startTime));
System.out.println(data);
}
}
结论非常明显啦,以后再使用IO读写文件的时候,多使用NIO MappedByteBuffer吧,毕竟NIO比老IO性能好太多啦。