我在开发阶段,在那里我有两个模块,从一个我得到输出作为一个OutputStream和第二个,它只接受InputStream。你知道如何将OutputStream转换为InputStream(反之亦然,我的意思是真的这样),我将能够连接这两个部分吗?
谢谢
我在开发阶段,在那里我有两个模块,从一个我得到输出作为一个OutputStream和第二个,它只接受InputStream。你知道如何将OutputStream转换为InputStream(反之亦然,我的意思是真的这样),我将能够连接这两个部分吗?
谢谢
当前回答
Though you cannot convert an OutputStream to an InputStream, java provides a way using PipedOutputStream and PipedInputStream that you can have data written to a PipedOutputStream to become available through an associated PipedInputStream. Sometime back I faced a similar situation when dealing with third party libraries that required an InputStream instance to be passed to them instead of an OutputStream instance. The way I fixed this issue is to use the PipedInputStream and PipedOutputStream. By the way they are tricky to use and you must use multithreading to achieve what you want. I recently published an implementation on github which you can use. Here is the link . You can go through the wiki to understand how to use it.
其他回答
ByteArrayOutputStream buffer = (ByteArrayOutputStream) aOutputStream;
byte[] bytes = buffer.toByteArray();
InputStream inputStream = new ByteArrayInputStream(bytes);
easystream开源库直接支持将OutputStream转换为InputStream: http://io-tools.sourceforge.net/easystream/tutorial/tutorial.html
// create conversion
final OutputStreamToInputStream<Void> out = new OutputStreamToInputStream<Void>() {
@Override
protected Void doRead(final InputStream in) throws Exception {
LibraryClass2.processDataFromInputStream(in);
return null;
}
};
try {
LibraryClass1.writeDataToTheOutputStream(out);
} finally {
// don't miss the close (or a thread would not terminate correctly).
out.close();
}
他们还列出了其他选项:http://io-tools.sourceforge.net/easystream/outputstream_to_inputstream/implementations.html
Write the data the data into a memory buffer (ByteArrayOutputStream) get the byteArray and read it again with a ByteArrayInputStream. This is the best approach if you're sure your data fits into memory. Copy your data to a temporary file and read it back. Use pipes: this is the best approach both for memory usage and speed (you can take full advantage of the multi-core processors) and also the standard solution offered by Sun. Use InputStreamFromOutputStream and OutputStreamToInputStream from the easystream library.
你需要一个中间类来缓冲。每次调用InputStream.read(byte[]…)时,缓冲类将用从OutputStream.write(byte[]…)传入的下一个块填充传入的字节数组。由于块的大小可能不相同,适配器类需要存储一定数量的块,直到它有足够的容量填满读缓冲区和/或能够存储任何缓冲区溢出。
这篇文章很好地分解了解决这个问题的几种不同方法:
http://blog.ostermiller.org/convert-java-outputstream-inputstream
老帖子,但可能会帮助别人,使用这种方式:
OutputStream out = new ByteArrayOutputStream();
...
out.write();
...
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(out.toString().getBytes()));
正如一些人已经回答的那样,没有有效的方法来“转换”一个OutputStream到一个InputStream。解决这类问题的技巧是将所有需要OutputStream的代码执行到它自己的线程中。通过使用管道流,我们可以将数据从创建的线程传输到InputStream中。
使用示例:
public static InputStream downloadFileAsStream(final String uriString) throws IOException {
final InputStream inputStream = runInOwnThreadWithPipedStreams((outputStream) -> {
try {
downloadUriToStream(uriString, outputStream);
} catch (final Exception e) {
LOGGER.error("Download of uri '{}' has failed", uriString, e);
}
});
return inputStream;
}
辅助功能:
public static InputStream runInOwnThreadWithPipedStreams(
final Consumer<OutputStream> outputStreamConsumer) throws IOException {
final PipedInputStream inputStream = new PipedInputStream();
final PipedOutputStream outputStream = new PipedOutputStream(inputStream);
new Thread(new Runnable() {
public void run() {
try {
outputStreamConsumer.accept(outputStream);
} finally {
try {
outputStream.close();
} catch (final IOException e) {
LOGGER.error("Closing outputStream has failed. ", e);
}
}
}
}).start();
return inputStream;
}
单元测试:
@Test
void testRunInOwnThreadWithPipedStreams() throws IOException {
final InputStream inputStream = LoadFileUtil.runInOwnThreadWithPipedStreams((OutputStream outputStream) -> {
try {
IOUtils.copy(IOUtils.toInputStream("Hello World", StandardCharsets.UTF_8), outputStream);
} catch (final IOException e) {
LoggerFactory.getLogger(LoadFileUtilTest.class).error(e.getMessage(), e);
}
});
final String actualResult = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
Assertions.assertEquals("Hello World", actualResult);
}