简体   繁体   English

如何使用NIO将InputStream写入File?

[英]How to use NIO to write InputStream to File?

I am using following way to write InputStream to 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();
}

I was wondering if this is the right way to use NIO. 我想知道这是否是使用NIO的正确方法。 I have read a method FileChannel.transferFrom , which takes three parameter: 我读过一个方法FileChannel.transferFrom ,它有三个参数:

  1. ReadableByteChannel src ReadableByteChannel src
  2. long position 多头头寸
  3. long count 长计数

In my case I only have src , I don't have the position and count , is there any way I can use this method to create the file? 在我的情况下,我只有src ,我没有positioncount ,有什么方法可以使用此方法来创建文件?

Also for Image is there any better way to create image only from InputStream and NIO? 另外对于Image,还有更好的方法只能从InputStream和NIO创建图像吗?

Any information would be very useful to me. 任何信息对我都非常有用。 There are similar questions here, in SO, but I cannot find any particular solution which suites my case. 这里有类似的问题,在SO中,但我找不到适合我的案例的特定解决方案。

I would use Files.copy 我会使用Files.copy

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

as for your version 至于你的版本

  1. ByteBuffer.allocateDirect is faster - Java will make a best effort to perform native I/O operations directly upon it. ByteBuffer.allocateDirect更快 - Java将尽最大努力直接执行本机I / O操作。

  2. Closing is unreliable, if first fails second will never execute. 关闭是不可靠的,如果第一次失败,则第二次永远不会执行。 Use try-with-resources instead, Channels are AutoCloseable too. 使用try-with-resources代替,Channels也是AutoCloseable

No it's not correct. 不,这不正确。 You run the risk of losing data. 您冒着丢失数据的风险。 The canonical NIO copy loop is as follows: 规范的NIO复制循环如下:

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

Note the changed loop conditions, which take care of flushing the output at EOS, and the use of compact() instead of clear(), which takes care of the possibility of short writes. 注意改变的循环条件,它负责在EOS上刷新输出,并使用compact()而不是clear(),来处理短写入的可能性。

Similarly the canonical transferTo()/transferFrom() loop is as follows: 类似地,规范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;
}

It must be called in a loop, as it isn't guaranteed to transfer the entire quantum. 它必须在循环中调用,因为它不能保证传输整个量子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM