JDK 1.4 中引入的新输入输出 (NIO) 库在标准 Java 代码中提供了高速的、面向块的 I/O。今天我们就简单的学习一下nio的知识。我笑,便面如春花,定是能感动人的,任他是谁。
nio的简单使用
FileInputStream、FileOutputStream和RandomAccessFile用于产生FileChannel。这些字节操纵流,与底层的nio特性一致。
一、FileChannel的产生
public void nioTest_1() { final int BUFFER_SIZE = 1024; try { // 向文件里面写入数据 FileChannel fc = new FileOutputStream("file/linux.txt").getChannel(); fc.write(ByteBuffer.wrap("I love you".getBytes())); fc.close(); // 向文件里面追加数据 fc = new RandomAccessFile("file/linux.txt", "rw").getChannel(); System.out.println(fc.position()); // 0 fc.position(fc.size()); fc.write(ByteBuffer.wrap(", china.".getBytes())); fc.close(); // 向文件里面读取数据 fc = new FileInputStream("file/linux.txt").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); fc.read(buffer); buffer.flip(); while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); // I love you, china. } } catch (Exception e) { e.printStackTrace(); } }
二、文件的复制功能
public void nioTest_2() { final int BUFFER_SIZE = 1024; try { FileChannel out = new FileOutputStream("file/huhx.txt").getChannel(); FileChannel in = new FileInputStream("file/linux.txt").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); while (in.read(buffer) != -1) { buffer.flip(); // 准备写数据 out.write(buffer); buffer.clear(); // 准备读数据 } out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } }
关于文件的复制,jdk提供了一个简单的方法实现。
public void nioTest_3() { final int BUFFER_SIZE = 1024; try { FileChannel out = new FileOutputStream("file/huhx.txt").getChannel(); FileChannel in = new FileInputStream("file/linux.txt").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); in.transferTo(0, in.size(), out); // out.transferFrom(in, 0, in.size()); 这个和上述实现的目标是一样的。 } catch (Exception e) { e.printStackTrace(); } }
三、buffer之间的转换
public void nioTest_4() { ByteBuffer buffer = ByteBuffer.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0, 'a'}); buffer.rewind(); System.out.println("Byte Buffer"); while (buffer.hasRemaining()) { System.out.println(buffer.position() + " -> " + buffer.get()); } IntBuffer intBuffer = ((ByteBuffer) buffer.rewind()).asIntBuffer(); System.out.println("Int Buffer"); while (intBuffer.hasRemaining()) { System.out.println(intBuffer.position() + " -> " + intBuffer.get()); } CharBuffer charBuffer = ((ByteBuffer) buffer.rewind()).asCharBuffer(); System.out.println("Char Buffer"); while (charBuffer.hasRemaining()) { System.out.println(charBuffer.position() + " -> " + charBuffer.get()); } }
运行的效果:
Byte Buffer 0 -> 0 1 -> 0 2 -> 0 3 -> 0 4 -> 0 5 -> 0 6 -> 0 7 -> 97 Int Buffer 0 -> 0 1 -> 97 Char Buffer 0 -> 1 -> 2 -> 3 -> a
四、存储器映射文件
public void nioTest_6() { final int length = 0x8FFFFFF; try { MappedByteBuffer out = new RandomAccessFile("file/huhx.txt", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length); for (int i = 0; i < length; i++) { out.put((byte) 'x'); } System.out.println("Finishing writing"); for (int i = length / 2; i < length / 2 + 6; i++) { System.out.print((char) out.get(i)); } } catch (Exception e) { e.printStackTrace(); } }
五、文件加锁
public void nioTest_7() { try { FileOutputStream fos = new FileOutputStream("file/huhx.txt", false); FileLock fileLock = fos.getChannel().tryLock(); if (fileLock != null) { System.out.println("Locked File"); Thread.sleep(1000); fos.write("hello world".getBytes()); fileLock.release(); System.out.println("Released Lock"); } fos.close(); } catch (Exception e) { e.printStackTrace(); } }