一尘不染

如何使用NIO将InputStream写入文件?

java

我使用下面的方法来写InputStreamFile

private void writeToFile(InputStream stream) throws IOException {
    String filePath = "C:\\Test.jpg";
    FileChannel outChannel = new FileOutputStream(filePath).getChannel();       
    ReadableByteChannel inChannel = Channels.newChannel(stream);
    ByteBuffer buffer = ByteBuffer.allocate(1024);

    while(true) {
        if(inChannel.read(buffer) == -1) {
            break;
        }

        buffer.flip();
        outChannel.write(buffer);
        buffer.clear();
    }

    inChannel.close();
    outChannel.close();
}

我想知道这是否是使用NIO的正确方法。我已经阅读了一个方法FileChannel.transferFrom,该方法带有三个参数:

  1. ReadableByteChannel src
  2. 好仓
  3. 长计

在我的情况下,我只有src,而没有positionand和count,有什么方法可以使用此方法来创建文件?

此外,对于Image,还有什么更好的方法可以仅从InputStream和NIO 创建映像?

任何信息对我来说都是非常有用的。在SO中也有类似的问题,但是我找不到适合我情况的任何特定解决方案。


阅读 498

收藏
2020-12-03

共1个答案

一尘不染

不,这是不正确的。您冒着丢失数据的风险。规范的NIO复制循环如下:

while (in.read(buffer) >= 0 || buffer.position() > 0)
{
  buffer.flip();
  out.write(buffer);
  buffer.compact();
}

请注意已更改的循环条件,该条件需要在EOS处刷新输出,而使用compact()代替条件clear(),则可以避免发生短写入的情况。

类似地,规范transferTo()/transferFrom()循环如下:

long offset = 0;
long quantum = 1024*1024; // or however much you want to transfer at a time
long count;
while ((count = out.transferFrom(in, offset, quantum)) > 0)
{
    offset += count;
}

它必须在循环中调用,因为不能保证传递整个量子。

2020-12-03