Java 将数据从ReadableByteChannel传输到文件

Java 将数据从ReadableByteChannel传输到文件,java,nio,Java,Nio,目标:解密来自一个源的数据,并将解密后的数据写入文件 try (FileInputStream fis = new FileInputStream(targetPath.toFile()); ReadableByteChannel channel = newDecryptedByteChannel(path, associatedData)) { FileChannel fc = fis.getChannel(); long position = 0; w

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

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);
    }
}
try(FileInputStream fis=newfileinputstream(targetPath.toFile());
ReadableByteChannel通道=newDecryptedByteChannel(路径,关联数据))
{
FileChannel fc=fis.getChannel();
长位置=0;
而(位置<??)
{
位置+=fc.transferFrom(通道、位置、块大小);
}
}
newDecryptedByteChannel(Path,byte[])
的实现不应该引起兴趣,它只返回一个ReadableByteChannel

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

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


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

这是
FileChannel的一个奇怪特性。transferFrom()
它从不告诉您流的结束。您必须独立地知道输入长度

为此,我只使用流:具体地说,一个
CipherInputStream
围绕一个
FileInputStream
BufferedInputStream
和一个
FileOutputStream


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

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

我能找到的转移方式是通过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);
}