[英]Get an input stream from an output stream
我有一个组件在输出流( ByteArrayOutputStream
)中给我数据,我需要将其写入SQL数据库的blob字段而不创建临时缓冲区,因此需要获取输入流。
根据这里和这里的答案,我提出了以下方法来从输出流中获取输入流:
private PipedInputStream getInputStream(ByteArrayOutputStream outputStream) throws InterruptedException
{
PipedInputStream pipedInStream = new PipedInputStream();
Thread copyThread = new Thread(new CopyStreamHelper(outputStream, pipedInStream));
copyThread.start();
// Wait for copy to complete
copyThread.join();
return pipedInStream;
}
class CopyStreamHelper implements Runnable
{
private ByteArrayOutputStream outStream;
private PipedInputStream pipedInStream;
public CopyStreamHelper (ByteArrayOutputStream _outStream, PipedInputStream _pipedInStream)
{
outStream = _outStream;
pipedInStream = _pipedInStream;
}
public void run()
{
PipedOutputStream pipedOutStream = null;
try
{
// write the original OutputStream to the PipedOutputStream
pipedOutStream = new PipedOutputStream(pipedInStream);
outStream.writeTo(pipedOutStream);
}
catch (IOException e)
{
// logging and exception handling should go here
}
finally
{
IOUtils.closeQuietly(pipedOutStream);
}
}
}
请注意,输出流已包含已写入的数据,最多可以运行1-2 MB。 但是无论在两个单独的线程或同一个线程中尝试执行此操作,我发现PipedInputStream
始终挂起以下内容:
Object.wait(long) line: not available [native method]
PipedInputStream.awaitSpace() line: not available
您的解决方案过于复杂
ByteArrayOutputStream baos = ...;
byte[] data = baos.toByteArray();
return new ByteArrayInputStream(data);
我已经设计了一个非常简单的演示来使用PipedInput / OutputStream。 它可能适合也可能不适合您的用例。
写入PipedOutputStream的生产类:
public class Producer implements Runnable {
private final PipedOutputStream pipedOutputStream;
private final PipedInputStream pipedInputStream;
public Producer() throws IOException {
this.pipedOutputStream = new PipedOutputStream();
this.pipedInputStream = new PipedInputStream(pipedOutputStream);
}
public PipedInputStream getPipedInputStream() {
return pipedInputStream;
}
@Override
public void run() {
try(InputStream inputStream = ByteStreams.limit(new RandomInputStream(), 100000)) {
// guava copy function
ByteStreams.copy(inputStream, pipedOutputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
pipedOutputStream.close();
} catch (IOException e) {
// no-op
}
}
}
public static void main(String[] args) throws IOException {
try {
Producer producer = new Producer();
Consumer consumer = new Consumer(producer);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
消费者只计算字节数:
public class Consumer implements Runnable {
private final Producer producer;
public Consumer(Producer producer) {
this.producer = producer;
}
@Override
public void run() {
try (PipedInputStream pipedInputStream = producer.getPipedInputStream()) {
int counter = 0;
while (pipedInputStream.read() != -1) {
counter++;
}
System.out.println(counter);
} catch (IOException e) {
e.printStackTrace();
}
}
}
在某种程度上,必须有一个缓冲区。 请参阅将输入流连接到输出流 。
我最喜欢的答案来自Dean Hiller:
void feedInputToOutput(InputStream in, OutputStream out) {
IOUtils.copy(in, out);
}
有关详细信息,请参阅api
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.