分享

Java nio入门教程详解(0022)

 360lec 2016-09-30

3.4.1 Channel-to-Channel传输

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

  1. public abstract class FileChannel extends AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {
  2.     // 这里仅列出部分API
  3.     public abstract long transferTo (long position, long count, WritableByteChannel target)
  4.     public abstract long transferFrom (ReadableByteChannel src, long position, long count)
  5. }

transferTo()transferFrom()方法允许将一个通道交叉连接到另一个通道,而不需要通过一个中间缓冲区来传递数据。只有FileChannel类有这两个方法,因此Channel-to-Channel传输中通道之一必须是FileChannel。您不能在socket通道之间直接传输数据,不过socket通道实现WritableByteChannelReadableByteChannel接口,因此文件的内容可以用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)。

  1. /*
  2.  *例 3-6 使用通道传输进行文件连结
  3.  */
  4. package com.ronsoft.books.nio.channels;
  5. import java.nio.channels.FileChannel;
  6. import java.nio.channels.WritableByteChannel;
  7. import java.nio.channels.Channels;
  8. import java.io.FileInputStream;
  9. /**
  10. * Test channel transfer. This is a very simplistic concatenation
  11. * program. It takes a list of file names as arguments, opens each
  12. * in turn and transfers (copies) their content to the given
  13. * WritableByteChannel (in this case, stdout).
  14. *
  15. * Created April 2002
  16. * @author Ron Hitchens (ron@ronsoft.com)
  17. */
  18. public class ChannelTransfer {
  19.     public static void main (String [] argv) throws Exception {
  20.         if (argv.length == 0) {
  21.             System.err.println ("Usage: filename ...");
  22.             return;
  23.         }
  24.         catFiles (Channels.newChannel (System.out), argv);
  25.     }
  26.     // Concatenate the content of each of the named files to
  27.     // the given channel. A very dumb version of 'cat'.
  28.     private static void catFiles (WritableByteChannel target, String [] files) throws Exception {
  29.         for (int i = 0; i < files.length; i++) {
  30.             FileInputStream fis = new FileInputStream(files [i]);
  31.             FileChannel channel = fis.getChannel();
  32.             channel.transferTo(0, channel.size(), target);
  33.             channel.close();
  34.             fis.close();
  35.         }
  36.     }
  37. }

Java nio入门教程详解(二十三)

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多