【发布时间】:2016-10-27 14:00:11
【问题描述】:
我正在使用管道输出流将OutputStream 转换为InputStream,因为AWS java sdk 不允许使用OutputStreams 将对象放在S3 上
我正在使用下面的代码,但是,它会间歇性地挂起。此代码位于 Web 应用程序中。目前应用程序没有负载...我只是在我的个人计算机上试用它。
ByteArrayOutputStream os = new ByteArrayOutputStream();
PipedInputStream inpipe = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(inpipe);
try {
String xmpXml = "<dc:description>somedesc</dc:description>"
JpegXmpRewriter rewriter = new JpegXmpRewriter();
rewriter.updateXmpXml(isNew1,os, xmpXml);
new Thread(new Runnable() {
public void run () {
try {
// write the original OutputStream to the PipedOutputStream
println "starting writeto"
os.writeTo(out);
out.close();
println "ending writeto"
} catch (IOException e) {
System.out.println("Some exception)
}
}
}).start();
ObjectMetadata metadata1 = new ObjectMetadata();
metadata1.setContentLength(os.size());
client.putObject(new PutObjectRequest("test-bucket", "167_sample.jpg", inpipe, metadata1));
}
catch (Exception e) {
System.out.println("Some exception")
}
finally {
isNew1.close()
os.close()
}
【问题讨论】:
-
作为参考,这里讨论了这种技术(避免再次复制 BAOS 的内容):stackoverflow.com/a/23874232/14955
-
你有线程转储(kill -QUIT)吗?
-
我知道那个解决方案。这就是我从那里得到我的狙击手的地方,这正是我在我的问题中所做的,不是吗?
-
您使用 BAOS 不会破坏管道流的优势吗?实际上,您应该做的是从您创建的线程中调用
rewriter.updateXmpXml(isNew1,out, xmpXml);。请注意,我写的是out,而不是os。 -
我同意@Thilo 的观点,收集到 BAOS 的优点是已知大小并且在上传开始之前知道成功。但是,一旦您将数据存储在 RAM 中,就没有必要再考虑启动另一个线程和在线程之间传递数据的复杂性了,只是为了解决一个愚蠢的 API 限制。
标签: java thread-safety java.util.concurrent java-threads