package io; import java.io.*; import java.nio.IntBuffer; import java.nio.channels.FileChannel; /** * Created by Administrator on 2018/4/6. */ public class MappedIO { private static int numOfInts=4000000; private static int numOfUbuffInts=200000; private abstract static class Tester{ private String name; public Tester(String name){this.name=name;} public void runTest(){ System.out.println(name+":"); try { long start=System.nanoTime(); test(); double duration=System.nanoTime()-start; System.out.format("%.2f\n",duration/1.0e9); }catch (Exception e){ throw new RuntimeException(e); } } public abstract void test() throws Exception; } private static Tester[] tests={ new Tester("Stream writer") { @Override public void test() throws Exception { DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File("temp.tmp")))); for(int i=0;i<numOfInts;i++){ dos.writeInt(i); } dos.close(); } }, new Tester("Mapped Write") { @Override public void test() throws Exception { FileChannel fileChannel=new RandomAccessFile("temp.tmp","rw").getChannel(); IntBuffer ib=fileChannel.map(FileChannel.MapMode.READ_WRITE,0,fileChannel.size()).asIntBuffer(); for(int i=0;i<numOfInts;i++){ ib.put(i); } fileChannel.close(); } }, new Tester("Stream Read") { @Override public void test() throws Exception { DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream("temp.tmp"))); for(int i=0;i<numOfInts;i++){ dis.readInt(); } dis.close(); } }, new Tester("Mapped read") { @Override public void test() throws Exception { FileChannel fileChannel=new FileInputStream(new File("temp.tmp")).getChannel(); IntBuffer ib=fileChannel.map(FileChannel.MapMode.READ_ONLY,0,fileChannel.size()).asIntBuffer(); while (ib.hasRemaining()){ ib.get(); } fileChannel.close(); } }, new Tester("Stream Read/write") { @Override public void test() throws Exception { RandomAccessFile rdf=new RandomAccessFile(new File("temp.tmp"),"rw"); rdf.writeInt(1); for(int i=0;i<numOfUbuffInts;i++){ rdf.seek(rdf.length()-4); rdf.writeInt(rdf.read()); } rdf.close(); } }, new Tester("Mapped Read/Write") { @Override public void test() throws Exception { FileChannel fileChannel=new RandomAccessFile(new File("temp.tmp"),"rw").getChannel(); IntBuffer id=fileChannel.map(FileChannel.MapMode.READ_WRITE,0,fileChannel.size()).asIntBuffer(); id.put(0); for(int i=1;i<numOfUbuffInts;i++){ id.put(id.get(i-1)) } fileChannel.close(); } } };
runTest()被用作是一种模板方法,为匿名内部子类中定义的test()的各种实现创建了测试框架。每一种测试类都执行一种测试,因此test()方法为我们进行各种I/O操作提供了原型。尽管映射写似乎要用到FileOutputStrem,但是映射文件中的输出必须使用RandomAccessFile。即使建立映射文件的花费很大,但是整体受益比I/O流来说还是很显著的。