给出一个学习的链接讲的很全。。
http://ifeve.com/java-nio-all/
上边的是中文翻译的这里是原地址:
http://tutorials.jenkov.com/java-nio/overview.html
Channel:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
Buffer:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
- Mappedyteuffer
Selector:
利用Channel与Buffer对文件的读写
import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.ObjectInputStream.GetField; import java.io.RandomAccessFile; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.regex.Pattern; public class Test{ public static void main(String[] args) throws IOException { RandomAccessFile accessFile = new RandomAccessFile(new File("/home/estar/Test/a.java"), "rw"); //获得文件通道 FileChannel fileChannel = accessFile.getChannel(); //分配缓冲区 ByteBuffer bf = ByteBuffer.allocate(1024); //首先判断一下是否有数据可读 int byteReads = fileChannel.read(bf); //如果缓冲区里有数据 while (byteReads != -1){ System.out.println("byteReads : " + byteReads); //切换到读模式 bf.flip(); //读position 到 limit之间的数据 while (bf.hasRemaining()) { System.out.println((char)bf.get()); } //清空读出来的数据 bf.clear(); //重新读取 byteReads = fileChannel.read(bf); } //写入数据之前首先清空一下缓冲区 bf.clear(); //放入数据 bf.put("AAHJKHJK".getBytes()); //将position置0 bf.flip(); fileChannel.write(bf); fileChannel.write(ByteBuffer.wrap("nixing".getBytes())); } }
实现两个文件内容的复制:
FileChannel in = new FileInputStream("/home/estar/Test/a.java").getChannel(), out = new FileOutputStream("/home/estar/Test/b.java").getChannel(); ByteBuffer buf = ByteBuffer.allocate(1024); while ((in.read(buf)) != -1){ buf.flip(); out.write(buf); buf.clear(); }
内存映射文件:
MapByteBuffer的与普通I/O的比较
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.ObjectInputStream.GetField; import java.io.RandomAccessFile; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.IntBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import javax.xml.datatype.Duration; /* * 尽管旧的I/O在用nio实现后性能有所提高, 但是“映射文件访问”往往可以更加显著地加快速度 */ public class Test { public static int numOfInts = 400000; //抽象类提供模板方法 public abstract static class Tester { String name; public Tester(String name) { this.name = name; } //模板方法 public void runTest() { System.out.print("test : " + name + " : "); long start = System.nanoTime(); test(); long end = System.nanoTime(); double duration = (end - start) / 1.0e9; System.out.format("%.2f ", duration); } public abstract void test(); } public static Tester[] tests = { /* * 匿名内部类提供模板的具体实现 */ new Tester("Stream Write:") { @Override public void test() { try { DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(new File( "tmp.tmp")))); for (int i = 0; i < numOfInts; ++i) { dos.writeInt(i); } dos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new Tester("Mapped Write:") { @Override public void test() { try { FileChannel fchinal = new RandomAccessFile("tmp.tmp", "rw") .getChannel(); try { IntBuffer intBuffer = fchinal.map( FileChannel.MapMode.READ_WRITE, 0, fchinal.size()) .asIntBuffer(); for (int i = 0; i < numOfInts; ++i) { intBuffer.put(i); } fchinal.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new Tester("Stream Read") { @Override public void test() { try { DataInputStream dis = new DataInputStream(new BufferedInputStream( new FileInputStream(new File("tmp.tmp")))); for (int i = 0; i < numOfInts; ++i) { dis.readInt(); } dis.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } },new Tester("Map Read") { @Override public void test() { FileChannel fChannel; try { fChannel = new RandomAccessFile("tmp.tmp", "rw").getChannel(); IntBuffer intBuffer = fChannel.map(FileChannel.MapMode.READ_WRITE, 0, fChannel.size()).asIntBuffer(); for (int i = 0; i < numOfInts; ++i) { intBuffer.get(); } fChannel.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new Tester("Stream Read/Write") { @Override public void test() { RandomAccessFile raf; try { raf = new RandomAccessFile("tmp.tmp", "rw"); raf.writeInt(1); for(int i = 0; i < numOfInts; ++i){ raf.seek(raf.length() - 4); raf.writeInt(raf.readInt()); } raf.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new Tester("Map Read/Write") { @Override public void test() { FileChannel fChannel; try { fChannel = new RandomAccessFile("tmp.tmp", "rw").getChannel(); IntBuffer intBuffer = fChannel.map(FileChannel.MapMode.READ_WRITE, 0, fChannel.size()).asIntBuffer(); intBuffer.put(1); for (int i = 1; i <= numOfInts; ++i) { intBuffer.put(intBuffer.get(i - 1)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; public static void main(String[] args) throws IOException { for (Tester tester : tests) { tester.runTest(); } } } 输出: test : Stream Write: : 0.06 test : Mapped Write: : 0.01 test : Stream Read : 0.06 test : Map Read : 0.01 test : Stream Read/Write : 3.43 test : Map Read/Write : 0.01