将 Java InputStream 的内容写入 OutputStream 的简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Easy way to write contents of a Java InputStream to an OutputStream
提问by Matt Sheppard
I was surprised to find today that I couldn't track down any simple way to write the contents of an InputStream
to an OutputStream
in Java. Obviously, the byte buffer code isn't difficult to write, but I suspect I'm just missing something which would make my life easier (and the code clearer).
今天我很惊讶地发现我无法找到任何简单的方法来在 Java 中将an 的内容写入InputStream
an OutputStream
。显然,字节缓冲区代码不难编写,但我怀疑我只是遗漏了一些可以让我的生活更轻松(并且代码更清晰)的东西。
So, given an InputStream
in
and an OutputStream
out
, is there a simpler way to write the following?
那么,给定 anInputStream
in
和 an OutputStream
out
,是否有更简单的方法来编写以下内容?
byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
out.write(buffer, 0, len);
len = in.read(buffer);
}
采纳答案by Ali Dehghani
Java 9
爪哇 9
Since Java 9, InputStream
provides a method called transferTo
with the following signature:
从 Java 9 开始,InputStream
提供了一个transferTo
使用以下签名调用的方法:
public long transferTo(OutputStream out) throws IOException
As the documentationstates, transferTo
will:
正如文档所述,transferTo
将:
Reads all bytes from this input stream and writes the bytes to the given output stream in the order that they are read. On return, this input stream will be at end of stream. This method does not close either stream.
This method may block indefinitely reading from the input stream, or writing to the output stream. The behavior for the case where the input and/or output stream is asynchronously closed, or the thread interrupted during the transfer, is highly input and output stream specific, and therefore not specified
从此输入流中读取所有字节,并按照读取顺序将字节写入给定的输出流。返回时,此输入流将位于流的末尾。此方法不会关闭任一流。
此方法可能会无限期地阻止从输入流读取或写入输出流。输入和/或输出流异步关闭或线程在传输期间中断的情况下的行为是高度特定于输入和输出流的,因此未指定
So in order to write contents of a Java InputStream
to an OutputStream
, you can write:
因此,为了编写Java内容的InputStream
一个OutputStream
,你可以这样写:
input.transferTo(output);
回答by Mike Stone
I think this will work, but make sure to test it... minor "improvement", but it might be a bit of a cost at readability.
我认为这会奏效,但请确保对其进行测试……微小的“改进”,但在可读性方面可能会有点成本。
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
回答by Arktronic
PipedInputStream and PipedOutputStream may be of some use, as you can connect one to the other.
PipedInputStream 和 PipedOutputStream 可能会有用,因为您可以将一个连接到另一个。
回答by WMR
There's no way to do this a lot easier with JDK methods, but as Apocalisp has already noted, you're not the only one with this idea: You could use IOUtilsfrom Jakarta Commons IO, it also has a lot of other useful things, that IMO should actually be part of the JDK...
有没有办法与JDK的方法来做到这一点轻松了许多,但Apocalisp已经指出的那样,你不是唯一一个有这样的想法:你可以使用IOUtils从Jakarta Commons的IO,它也有很多其他有用的东西, IMO实际上应该是JDK的一部分......
回答by Mikezx6r
As WMR mentioned, org.apache.commons.io.IOUtils
from Apache has a method called copy(InputStream,OutputStream)
which does exactly what you're looking for.
正如 WMR 所提到的,org.apache.commons.io.IOUtils
来自 Apache 有一个方法叫做copy(InputStream,OutputStream)
,它完全符合你的要求。
So, you have:
所以你有了:
InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();
...in your code.
...在你的代码中。
Is there a reason you're avoiding IOUtils
?
你有什么理由回避IOUtils
吗?
回答by Dilum Ranatunga
PipedInputStream
and PipedOutputStream
should only be used when you have multiple threads, as noted by the Javadoc.
PipedInputStream
并且PipedOutputStream
只应在您有多个线程时使用,如Javadoc 所述。
Also, note that input streams and output streams do not wrap any thread interruptions with IOException
s... So, you should consider incorporating an interruption policy to your code:
另外,请注意输入流和输出流不会用IOException
s包装任何线程中断......因此,您应该考虑将中断策略合并到您的代码中:
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();
}
}
This would be an useful addition if you expect to use this API for copying large volumes of data, or data from streams that get stuck for an intolerably long time.
如果您希望使用此 API 来复制大量数据,或者从卡住了无法忍受的长时间的流中复制数据,这将是一个有用的补充。
回答by Andrew Mao
Another possible candidate are the Guava I/O utilities:
另一个可能的候选者是 Guava I/O 实用程序:
http://code.google.com/p/guava-libraries/wiki/IOExplained
http://code.google.com/p/guava-libraries/wiki/IOExplained
I thought I'd use these since Guava is already immensely useful in my project, rather than adding yet another library for one function.
我想我会使用这些,因为 Guava 在我的项目中已经非常有用,而不是为一个函数添加另一个库。
回答by Alexander Volkov
I think it's better to use a large buffer, because most of the files are greater than 1024 bytes. Also it's a good practice to check the number of read bytes to be positive.
我认为最好使用大缓冲区,因为大多数文件都大于 1024 字节。此外,检查读取字节数是否为正数也是一个好习惯。
byte[] buffer = new byte[4096];
int n;
while ((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
out.close();
回答by Jordan LaPrise
Simple Function
简单的功能
If you only need this for writing an InputStream
to a File
then you can use this simple function:
如果您只需要它来写入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();
}
}
回答by user1079877
If you are using Java 7, Files(in the standard library) is the best approach:
如果您使用的是 Java 7,文件(在标准库中)是最好的方法:
/* You can get Path from file also: file.toPath() */
Files.copy(InputStream in, Path target)
Files.copy(Path source, OutputStream out)
Edit: Of course it's just useful when you create one of InputStream or OutputStream from file. Use file.toPath()
to get path from file.
编辑:当然,当您从文件创建 InputStream 或 OutputStream 之一时,它很有用。用于file.toPath()
从文件中获取路径。
To write into an existing file (e.g. one created with File.createTempFile()
), you'll need to pass the REPLACE_EXISTING
copy option (otherwise FileAlreadyExistsException
is thrown):
要写入现有文件(例如使用File.createTempFile()
),您需要传递REPLACE_EXISTING
复制选项(否则FileAlreadyExistsException
会抛出):
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)
回答by DejanLekic
Use Commons Net's Util class:
使用 Commons Net 的 Util 类:
import org.apache.commons.net.io.Util;
...
Util.copyStream(in, out);