当前位置:  开发笔记 > 编程语言 > 正文

将Java InputStream的内容写入OutputStream的简便方法

如何解决《将JavaInputStream的内容写入OutputStream的简便方法》经验,为你挑选了12个好方法。

我惊讶地发现,今天,我不能追查任何简单的方法的内容写入InputStreamOutputStreamJava中.显然,字节缓冲区代码并不难写,但我怀疑我只是遗漏了一些会让我的生活更轻松(代码更清晰)的东西.

那么,给定一个InputStream in和一个OutputStream out,是否有更简单的方法来编写以下内容?

byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
    out.write(buffer, 0, len);
    len = in.read(buffer);
}

Mikezx6r.. 392

正如WMR所提到的,org.apache.commons.io.IOUtils从Apache有一个方法copy(InputStream,OutputStream),它正是你正在寻找的.

所以你有了:

InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();

...在你的代码中.

你有没有理由避免IOUtils



1> Mikezx6r..:

正如WMR所提到的,org.apache.commons.io.IOUtils从Apache有一个方法copy(InputStream,OutputStream),它正是你正在寻找的.

所以你有了:

InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();

...在你的代码中.

你有没有理由避免IOUtils


我正在为我正在构建的移动应用程序避开它,因为它的应用程序大小增加了五倍,以节省5行代码.
值得一提的是,`in`和`out`必须在finally块中的代码末尾关闭
@basZero或者尝试使用资源块.

2> user1079877..:

如果您使用的是Java 7,则文件(在标准库中)是最佳方法:

/* You can get Path from file also: file.toPath() */
Files.copy(InputStream in, Path target)
Files.copy(Path source, OutputStream out)

编辑:当然,从文件创建一个InputStream或OutputStream时它非常有用.用于file.toPath()从文件中获取路径.

要写入现有文件(例如,使用其创建的文件File.createTempFile()),您需要传递REPLACE_EXISTING复制选项(否则FileAlreadyExistsException抛出):

Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)


我不认为这实际上解决了问题,因为一端是路径.虽然您可以获取文件的路径,但据我所知,您无法获得任何通用流(例如,通过网络的一个).
有趣的是,JDK还有一个`Files.copy()`,它接受两个流,并且是所有其他`Files.copy()`函数转发到的,以便进行实际的复制工作.但是,它是私有的(因为它实际上并不涉及那个阶段的路径或文件),并且看起来*完全*就像OP自己的问题中的代码(加上一个return语句).没有开放,没有关闭,只是一个复制循环.
仅供参考,**文件`不适用于**Android**的Java 1.7.我被这刺痛了:http://stackoverflow.com/questions/24869323/android-import-java-nio-file-files-cannot-be-resolved
CopyOptions是任意的!你可以把它放在这里,如果你想要它.
现在*这*是我要找的!JDK来救援,不需要另外一个库
虽然+1在我的情况下仍然有用,因为我在输出端有一个真实的文件!

3> Ali Dehghani..:
Java 9

从Java 9开始,InputStream提供了一个transferTo使用以下签名调用的方法:

public long transferTo(OutputStream out) throws IOException

如文档所述,transferTo将:

从此输入流中读取所有字节,并按读取顺序将字节写入给定的输出流.返回时,此输入流将位于流的末尾.此方法不会关闭任一流.

此方法可能会无限期地阻止从输入流中读取或写入输出流.输入和/或输出流异步关闭或传输过程中线程中断的情况下的行为是高度输入和输出流特定的,因此未指定

因此,为了编写Java内容的InputStream一个OutputStream,你可以这样写:

input.transferTo(output);


你应该尽可能多地选择`File.copy`.它以本机代码实现,因此可以更快.只有当两个流都不是FileInputStream/FileOutputStream时才应使用`transferTo`.

4> Mike Stone..:

我认为这样可行,但一定要测试它......轻微的"改进",但可读性可能有点费用.

byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}


我建议使用至少10KB到100KB的缓冲区.这并不多,可以加速大量复制大量数据.
@Blauhirn:这是不正确的,因为根据`InputStream`合同完全合法,读取任意次数返回0.根据`OutputStream`契约,write方法必须接受0的长度,并且只应在`len`为负时抛出异常.
你可能想说`while(len> 0)`而不是`!= -1`,因为后者在使用`read(byte b [],int off,int len)`-method时也会返回0,抛出异常@`out.write`

5> Andrejs..:

使用番石榴ByteStreams.copy():

ByteStreams.copy(inputStream, outputStream);


之后不要忘记关闭溪流!

6> Jordan LaPri..:

简单的功能

如果您只需InputStream要将其写入a,File那么您可以使用这个简单的函数:

private void copyInputStreamToFile( InputStream in, File file ) {
    try {
        OutputStream out = new FileOutputStream(file);
        byte[] buf = new byte[1024];
        int len;
        while((len=in.read(buf))>0){
            out.write(buf,0,len);
        }
        out.close();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


功能很棒,谢谢.你需要把`close()`调用放在`finally`块中吗?
您可能应该在实际实现中包含finally块而不是吞下异常.此外,关闭传递给方法的InputStream有时会被调用方法意外,因此应该考虑它是否是他们想要的行为.
为什么在IOException足够时捕获Exception?

7> Dilum Ranatu..:

PipedInputStream并且PipedOutputStream只应在有多个线程时使用,如Javadoc所述.

另请注意,输入流和输出流不会使用IOExceptions 包装任何线程中断...因此,您应该考虑在代码中加入中断策略:

byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
    out.write(buffer, 0, len);
    len = in.read(buffer);
    if (Thread.interrupted()) {
        throw new InterruptedException();
    }
}

如果您希望使用此API来复制大量数据,或者将数据从流中陷入无法忍受的长时间,这将是一个有用的补充.



8> BullyWiiPlaz..:

JDK所以它好像有没有笨重的第三方库(这可能不做什么不同呢)没有"容易"的方式使用相同的代码.以下内容直接复制自java.nio.file.Files.java:

// buffer size used for reading and writing
    private static final int BUFFER_SIZE = 8192;

/**
     * Reads all bytes from an input stream and writes them to an output stream.
     */
    private static long copy(InputStream source, OutputStream sink)
        throws IOException
    {
        long nread = 0L;
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = source.read(buf)) > 0) {
            sink.write(buf, 0, n);
            nread += n;
        }
        return nread;
    }


嗯 遗憾的是,这个特定的调用是私有的,没有别的选择,只能将其复制到自己的实用程序类中,因为有可能您不是在处理文件,而是一次处理两个套接字。

9> holmis83..:

对于那些使用Spring框架的人来说,有一个有用的StreamUtils类:

StreamUtils.copy(in, out);

以上并没有关闭流.如果要在复制后关闭流,请使用FileCopyUtils类:

FileCopyUtils.copy(in, out);



10> WMR..:

使用JDK方法无法轻松实现这一点,但正如Apocalisp已经指出的那样,你不是唯一一个有这个想法的人:你可以使用来自Jakarta Commons IO的IOUtils,它还有很多其他有用的东西, IMO实际上应该是JDK的一部分......



11> Sivakumar..:

使用Java7和try-with-resources,附带简化且可读的版本.

    try(InputStream inputStream     =   new FileInputStream("C:\\mov.mp4");
        OutputStream outputStream   =   new FileOutputStream("D:\\mov.mp4")){

        byte[] buffer    =   new byte[10*1024];

        for (int length; (length = inputStream.read(buffer)) != -1; ){
            outputStream.write(buffer, 0, length);
        }

    }catch (FileNotFoundException exception){
        exception.printStackTrace();
    }catch (IOException ioException){
        ioException.printStackTrace();
    }


在循环内冲洗是非常适得其反的.

12> Jin Kwon..:

这就是我使用最简单的for循环的方式。

private void copy(final InputStream in, final OutputStream out)
    throws IOException {
    final byte[] b = new byte[8192];
    for (int r; (r = in.read(b)) != -1;) {
        out.write(b, 0, r);
    }
}

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有