主要对nio的读效率进行对比,代码如下:
public class NIOTest {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub // nioReadTest1(); // nioReadTest2(); // nioReadTest3(); // nioReadTest4(); nioReadTest5(); // nioReadTest6(); }private static void nioReadTest1() throws Exception {
FileInputStream in = new FileInputStream(new File("data")); FileChannel channel = in.getChannel(); ByteBuffer buf = ByteBuffer.allocate(1024); int readCount = -1; long totalCount = 0; long start = System.currentTimeMillis(); while ((readCount = channel.read(buf)) != -1) { totalCount += readCount; buf.flip(); // hand data buf.clear();}
long end = System.currentTimeMillis(); System.out.println("读取:" + totalCount + "个字节,耗时:" + (end - start)); channel.close(); }private static void nioReadTest2() throws Exception {
RandomAccessFile raf = new RandomAccessFile(new File("data"), "r"); FileChannel channel = raf.getChannel(); ByteBuffer buf = ByteBuffer.allocate(1024); int readCount = -1; long totalCount = 0; long start = System.currentTimeMillis(); while ((readCount = channel.read(buf)) != -1) { totalCount += readCount; buf.flip(); // hand data buf.clear();}
long end = System.currentTimeMillis(); System.out.println("读取:" + totalCount + "个字节,耗时:" + (end - start)); channel.close(); }private static void nioReadTest3() throws Exception {
FileChannel channel = FileChannel.open(Paths.get("data"), StandardOpenOption.READ); ByteBuffer buf = ByteBuffer.allocate(1024); int readCount = -1; long totalCount = 0; long start = System.currentTimeMillis(); while ((readCount = channel.read(buf)) != -1) { totalCount += readCount; buf.flip(); // hand data buf.clear();}
long end = System.currentTimeMillis(); System.out.println("读取:" + totalCount + "个字节,耗时:" + (end - start)); channel.close(); }private static void nioReadTest4() throws Exception {
SeekableByteChannel channel = Files.newByteChannel(Paths.get("data"), StandardOpenOption.READ); ByteBuffer buf = ByteBuffer.allocate(1024); int readCount = -1; long totalCount = 0; long start = System.currentTimeMillis(); while ((readCount = channel.read(buf)) != -1) { totalCount += readCount; buf.flip(); // hand data buf.clear();}
long end = System.currentTimeMillis(); System.out.println("读取:" + totalCount + "个字节,耗时:" + (end - start)); channel.close(); }private static void nioReadTest5() throws Exception {
FileChannel channel = FileChannel.open(Paths.get("data"), StandardOpenOption.READ); ByteBuffer buf = ByteBuffer.allocateDirect(1024*1024*1024); int readCount = -1; long totalCount = 0; long start = System.currentTimeMillis(); while ((readCount = channel.read(buf)) != -1) { totalCount += readCount; buf.flip(); // hand data buf.clear();}
long end = System.currentTimeMillis(); System.out.println("读取:" + totalCount + "个字节,耗时:" + (end - start)); channel.close(); }private static void nioReadTest6() throws Exception {
FileChannel channel = FileChannel.open(Paths.get("data"), StandardOpenOption.READ); MappedByteBuffer mapBuf = channel.map(MapMode.READ_ONLY, 0, channel.size()); mapBuf.load(); System.out.println(mapBuf.isLoaded()); byte[] data = new byte[1024]; int lop = 1024 * 1024; long start = System.currentTimeMillis(); for(int i=0;i<lop;i++){ mapBuf.get(data); } long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - start)); channel.close(); }}
对比结果:FileInputStream 、RandomAccessFile 、FileChannel.open、Files.newByteChannel四种打开FileChannel的方式、读取效率差不多;普通的ByteBuffer与DirectByteBuffer其实差别不是很大,但是DirectByteBuffer会快点;MappedByteBuffer就要快很多了,一般对于大文件建议采用这种方式