【问题标题】:When Use FileChannel to read()/write() files?何时使用 FileChannel 读取()/写入()文件?
【发布时间】:2019-04-18 02:09:24
【问题描述】:

我正在阅读Thinking in Java一书,它解释了java.nio.* 包,并说NIO 比使用传统IO 流读写文件要快。为什么?

我查看了以下信息:

  • IO流是面向字节的,传统IO处理单元是字节,而NIO处理单元是块(字节数组),但是我认为传统IO也可以通过BufferedFile*直接处理块(字节数组),传统IO也有direct 处理字节数组的方法

    private native int readBytes(byte b[], int off, int len) throws IOException;
    
  • IO是阻塞读,NIO可以是非阻塞的,但是我发现文件NIO只能是非阻塞的,那么NIO就没有优势了。

  • 我认为需要使用NIO一般是其他需要使用NIO的优势,比如:

     transferTo()/transferFrom()
    

那么,什么时候应该使用 NIO 进行文件读写呢?为什么比传统IO快?正确的使用方法是什么?我应该只在读写文件时使用IO还是NIO?

【问题讨论】:

  • 私有方法不是 API 的一部分。 '没用'并不是因为缺少非阻塞模式。这本书真的说“更快”吗?还是“可以更快”?还是“更可扩展”?

标签: java nio java-io


【解决方案1】:

只有两种情况FileChannelFileInputStreamFileOutputStream 快。

第一个是当您可以使用堆外(“直接”)ByteBuffer 来保存数据时,它不会被复制到 Java 堆中。例如,如果您正在编写一个将静态文件传递到套接字的 Web 服务器,那么使用 FileInputStreamSocketChannel 而不是 FileInputStreamSocketOutputStream 会更快。

在我看来,这些案例非常少见。通常,当您在 Java 中读取(或写入)文件时,您将对数据进行处理。在这种情况下,您无法避免将数据复制到堆中。

FileChannel 的另一个用途是创建一个MappedByteBuffer 以随机访问文件的内容。这比使用RandomAccessFile 快得多,因为它用利用操作系统分页机制的内存访问代替了对操作系统内核的显式调用。

如果您刚刚开始使用 Java 中的 I/O,我建议您坚持使用 java.io 中的类,除非您能够解释为什么切换到 java.nio 会提高性能。使用面向流的抽象比使用面向块的抽象要容易得多。

【讨论】:

  • 谢谢你的回答,我也非常同意你的观点。看来我应该理解错书的意思了。
猜你喜欢
  • 1970-01-01
  • 2010-09-10
  • 2013-03-14
  • 1970-01-01
  • 2011-03-21
  • 2011-10-16
  • 1970-01-01
  • 2015-07-26
  • 2010-12-21
相关资源
最近更新 更多