nio 实现从写入流复制到输入流

话就很少说了,直接上代码: 架构


package com.yao.nio.channel; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; public class ChannelCopy { public static void main(String[] args) throws IOException { ReadableByteChannel src = Channels.newChannel(System.in); WritableByteChannel desc = Channels.newChannel(System.out); copy1(src,desc); src.close(); desc.close(); } private static void copy1(ReadableByteChannel src,WritableByteChannel desc) throws IOException{ ByteBuffer buffer = ByteBuffer.allocate(16*1024); while(src.read(buffer) != -1){ buffer.flip(); desc.write(buffer); buffer.compact(); } //可能有阻塞的没有写入通道 buffer.flip(); while (buffer.hasRemaining()) { desc.write(buffer); } } //和方法一功能同样 private static void copy2(ReadableByteChannel src,WritableByteChannel desc) throws IOException{ ByteBuffer buffer = ByteBuffer.allocate(16*1024); while (src.read(buffer) != -1) { buffer.flip(); while(buffer.hasRemaining()){ desc.write(buffer); } buffer.clear(); } } }package com.yao.nio.channel; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; public class ChannelCopy { public static void main(String[] args) throws IOException { ReadableByteChannel src = Channels.newChannel(System.in); WritableByteChannel desc = Channels.newChannel(System.out); copy1(src,desc); src.close(); desc.close(); } private static void copy1(ReadableByteChannel src,WritableByteChannel desc) throws IOException{ ByteBuffer buffer = ByteBuffer.allocate(16*1024); while(src.read(buffer) != -1){ buffer.flip(); desc.write(buffer); buffer.compact(); } //可能有阻塞的没有写入通道 buffer.flip(); while (buffer.hasRemaining()) { desc.write(buffer); } } //和方法一功能同样 private static void copy2(ReadableByteChannel src,WritableByteChannel desc) throws IOException{ ByteBuffer buffer = ByteBuffer.allocate(16*1024); while (src.read(buffer) != -1) { buffer.flip(); while(buffer.hasRemaining()){ desc.write(buffer); } buffer.clear(); } } }

其中copy1和copy2的功能是同样的,留意一下它们的差异。由于数据在传输的过程当中调用 write 出现数据阻塞的时候,可能会出现有些数据尚未彻底写到输出通道。因此要用 hasRemaining() 判断一下再继续写。 google

注意到copy1用到的是 buffer.compact() 压缩方法,若是缓冲区中全部数据都读出后它的实现是和 buffer.clear()同样的。不过若是还有留下的数据 compact() 能够继续把没有读入的继续到下次读。 spa


转载于:https://my.oschina.net/jamaly/blog/312636.net