java nio入门教程详解_Java nio入门教程详解(0022)

3.4.1 Channel-to-Channel传输

由于经常需要从一个位置将文件数据批量传输到另一个位置,FileChannel类添加了一些优化方法来提高该传输过程的效率: public abstract class FileChannel extends AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {

// 这里仅列出部分API

public abstract long transferTo (long position, long count, WritableByteChannel target)

public abstract long transferFrom (ReadableByteChannel src, long position, long count)

}

transferTo()和transferFrom()方法允许将一个通道交叉连接到另一个通道,而不需要通过一个中间缓冲区来传递数据。只有FileChannel类有这两个方法,因此Channel-to-Channel传输中通道之一必须是FileChannel。您不能在socket通道之间直接传输数据,不过socket通道实现WritableByteChannel和ReadableByteChannel接口,因此文件的内容可以用transferTo()方法传输给一个socket通道,或者也可以用transferFrom()方法将数据从一个socket通道直接读取到一个文件中。

直接的通道传输不会更新与某个FileChannel关联的position值。请求的数据传输将从position参数指定的位置开始,传输的字节数不超过count参数的值。实际传输的字节数会由方法返回,可能少于您请求的字节数。

对于传输数据来源是一个文件的transferTo()方法,如果position + count的值大于文件的size值,传输会在文件尾的位置终止。假如传输的目的地是一个非阻塞模式的socket通道,那么当发送队列(send queue)满了之后传输就可能终止,并且如果输出队列(output queue)已满的话可能不会发送任何数据。类似地,对于transferFrom()方法:如果来源src是另外一个FileChannel并且已经到达文件尾,那么传输将提早终止;如果来源src是一个非阻塞socket通道,只有当前处于队列中的数据才会被传输(可能没有数据)。由于网络数据传输的非确定性,阻塞模式的socket也可能会执行部分传输,这取决于操作系统。许多通道实现都是提供它们当前队列中已有的数据而不是等待您请求的全部数据都准备好。

此外,请记住:如果传输过程中出现问题,这些方法也可能抛出java.io.IOException异常。

Channel-to-Channel传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候。某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输。对于大量的数据传输,这会是一个巨大的帮助(参见例 3-6)。/*

*例 3-6 使用通道传输进行文件连结

*/

package com.ronsoft.books.nio.channels;

import java.nio.channels.FileChannel;

import java.nio.channels.WritableByteChannel;

import java.nio.channels.Channels;

import java.io.FileInputStream;

/**

* Test channel transfer. This is a very simplistic concatenation

* program. It takes a list of file names as arguments, opens each

* in turn and transfers (copies) their content to the given

* WritableByteChannel (in this case, stdout).

*

* Created April 2002

* @author Ron Hitchens (ron@ronsoft.com)

*/

public class ChannelTransfer {

public static void main (String [] argv) throws Exception {

if (argv.length == 0) {

System.err.println ("Usage: filename ...");

return;

}

catFiles (Channels.newChannel (System.out), argv);

}

// Concatenate the content of each of the named files to

// the given channel. A very dumb version of 'cat'.

private static void catFiles (WritableByteChannel target, String [] files) throws Exception {

for (int i = 0; i < files.length; i++) {

FileInputStream fis = new FileInputStream(files [i]);

FileChannel channel = fis.getChannel();

channel.transferTo(0, channel.size(), target);

channel.close();

fis.close();

}

}

}

0

0

我们认为:用户的主要目的,是为了获取有用的信息,而不是来点击广告的。因此本站将竭力做好内容,并将广告和内容进行分离,确保所有广告不会影响到用户的正常阅读体验。用户仅凭个人意愿和兴趣爱好点击广告。

我们坚信:只有给用户带来价值,用户才会给我们以回报。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值