在 Java NIO 中,如果两个通道中有一个是 FileChannel,那你可以直接将数据从一个 channel(译者注:channel
中文常译作通道)传输到另外一个 channel。
transferFrom():
FileChannel 的 transferFrom()方法可以将数据从源通道传输到 FileChannel 中(译者注:这个方法在 JDK 文档中
的解释为将字节从给定的可读取字节通道传输到此通道的文件中)。下面是一个简单的例子:
Java Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
|
/** * Created by 321695 on 2016/11/16. */ public class ChannelTransferTest { public static void main( String [] args) { RandomAccessFile fromFile = null; FileChannel fromChannel = null; RandomAccessFile toFile = null; FileChannel toChannel = null; try { /**创建文件随机访问类实例*/ fromFile = new RandomAccessFile( "E:/Dubbox/dubbo/nio-demo/src/main/resources/fromFile.txt" , "rw" ); /**取fromChannel实例*/ fromChannel = fromFile.getChannel(); /**创建文件随机访问类实例*/ toFile = new RandomAccessFile( "E:/Dubbox/dubbo/nio-demo/src/main/resources/toFile.txt" , "rw" ); /**取toChannel实例*/ toChannel = toFile.getChannel(); long position = 0 ; long count = 0 ; count = fromChannel.size(); /**将fromChannel中的数据传输到toChannel中*/ toChannel.transferFrom(fromChannel, position, count); /**创建一个容量为48字节的buffer*/ ByteBuffer buffer = ByteBuffer.allocate( 1024 ); /**读取数据到buffer中*/ toChannel.position( 0 ); int bytesRead = toChannel.read(buffer); while (bytesRead != - 1 ) { System.out.println( "Read:" + bytesRead); /**反转buffer*/ buffer.flip(); /**若buffer中还有元素,打印出来*/ while (buffer.hasRemaining()) { System.out.print(( char ) buffer.get()); } /**清空buffer*/ buffer.clear(); /**继续处理未完成数据*/ bytesRead = toChannel.read(buffer); } } catch (IOException e) { System.out.println( "" + e); e.printStackTrace(); } finally { try { fromFile.close(); fromChannel.close(); toFile.close(); toChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
示例代码,读的是toChannel,打印出来的内容确实来自fromFile,由此可见,transferFrom()方法完成了通道之间的数据传输
方法的输入参数 position 表示从 position 处开始向目标文件写入数据,count 表示最多传输的字节数。如果源通道的剩余空间小于 count 个字节,则所传输的字节数要小于请求的字节数。
此外要注意,在 SoketChannel 的实现中,SocketChannel 只会传输此刻准备好的数据(可能不足 count 字节)。
因此,SocketChannel 可能不会将请求的所有数据(count 个字节)全部传输到 FileChannel 中。
transferTo():
transferTo()方法将数据从 FileChannel 传输到其他的 channel 中。下面是一个简单的例子:
RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel fromChannel = fromFile.getChannel();
RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
FileChannel toChannel = toFile.getChannel();
long position = 0;
long count = fromChannel.size();
fromChannel.transferTo(position, count, toChannel);
上面所说的关于 SocketChannel 的问题在 transferTo()方法中同样存在。SocketChannel 会一直传输数据直到目标buffer 被填满。