【问题标题】:Transfer data from ReadableByteChannel to file将数据从 ReadableByteChannel 传输到文件
【发布时间】:2018-10-23 00:50:53
【问题描述】:

目标:从一个来源解密数据并将解密后的数据写入文件。

try (FileInputStream fis = new FileInputStream(targetPath.toFile());
        ReadableByteChannel channel = newDecryptedByteChannel(path, associatedData))
{
    FileChannel fc = fis.getChannel();
    long position = 0;
    while (position < ???)
    {
        position += fc.transferFrom(channel, position, CHUNK_SIZE);
    }
}

newDecryptedByteChannel(Path,byte[]) 的实现应该没什么意思,它只是返回一个 ReadableByteChannel。

问题:结束while循环的条件是什么?何时到达“字节通道结束”? transferFrom 是这里的正确选择吗?

This question 可能是相关的(答案是将计数设置为Long.MAX_VALUE)。不幸的是,这对我没有帮助,因为文档说最多可以传输 count 个字节,具体取决于通道的性质和状态。

另一个想法是只检查实际传输的字节数是否为 0(从transferFrom 返回),但如果源通道是非阻塞的并且在其中立即可用的字节数少于 count,则此条件可能为真输入缓冲区。

【问题讨论】:

    标签: java nio


    【解决方案1】:

    FileChannel. transferFrom() 的奇怪功能之一是它从不告诉您有关流结束的信息。您必须独立知道输入长度。

    我会为此使用流:具体来说,BufferedInputStream 周围是 FileInputStream 周围的 CipherInputStreamFileOutputStream

    但是您发布的代码无论如何都没有任何意义。它行不通。您正在传输到输入文件,并通过从FileInputStream 派生的通道,因此它是只读的,因此transferFrom() 将引发异常。

    【讨论】:

      【解决方案2】:

      正如@user207421 所评论的,当您从 ReadableByteChannel 读取时,目标通道需要从 FileOutputStream 而不是 FileInputStream 派生。在代码中结束循环的条件应该是 ReadableByteChannel 底层文件的大小,除非您能够获取 FileChannel 并通过其 size 方法找到大小,否则无法从中获取。

      我能找到的传输方式是通过 ByteBuffer 如下。

      ByteBuffer buf = ByteBuffer.allocate(1024*8);
      while(readableByteChannel.read(buf)!=-1)
      {
        buf.flip();
        fc.write(buf);  //fc is FileChannel derived from FileOutputStream
        buf.compact();
      }
      
      buf.flip();
      while(buf.hasRemainig())
      {
        fc.write(buf);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多