如何使用NIO将InputStream写入File?

我使用以下方式将InputStream写入File

 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 ,我没有positioncount ,有什么方法可以使用此方法来创建文件?

另外对于Image,还有更好的方法只能从InputStream和NIO创建图像吗?

任何信息对我都非常有用。 这里有类似的问题,在SO中,但我找不到适合我的案例的特定解决方案。

不,这不正确。 您冒着丢失数据的风险。 规范的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; } 

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

我会使用Files.copy

 Files.copy(is, Paths.get(filePath)); 

至于你的版本

  1. ByteBuffer.allocateDirect更快 – Java将尽最大努力直接执行本机I / O操作。

  2. 关闭是不可靠的,如果第一次失败,则第二次永远不会执行。 使用try-with-resources代替,Channels也是AutoCloseable