[英]InputStream wrapper that closes the stream once reading is done
在spring和hibernate的项目中,我遇到了一些问题,因为没有关闭提供给Blob的流。
Blob blob = Hibernate.getLobCreator(currentSession).createBlob(inputStream, size);
我不能使用诸如try with resources
东西try with resources
因为仅在事务提交后才读取流。 我也尝试过使用休眠的@PostPersist
关闭流。 它可以在持久的情况下工作,但是会导致已经使用CascadeType.MERGE
场景释放Blob的问题。
我的一位朋友提出了一种处理此问题的方法。 基本上,他的想法是编写一个包装,一旦读取完成,该包装将关闭流。
import java.io.IOException;
import java.io.InputStream;
public class SelfClosingInputStream extends InputStream {
private InputStream inputStream;
public SelfClosingInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public int read() throws IOException {
try {
int val = this.inputStream.read();
if (val != -1) {
return val;
} else {
this.inputStream.close();
return -1;
}
} catch (Exception e) {
this.inputStream.close();
throw e;
}
}
}
我已经做了一个简单的测试,它可以工作。 我了解if检查可能存在性能问题。 但是,我认为这还有其他警告。 有人可以阐明这些吗?
Blob blob = Hibernate.getLobCreator(currentSession).createBlob(new SelfClosingInputStream(inputStream), size);
PS:我已经在代码审查中将其张贴在这里 ,但是只有很少的回复。 因此,在这里重新发布一些更新。
更新:
从代码审查中收到了大量反馈。 这个答案似乎提供了最正确的方法。
进一步的https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/input/AutoCloseInputStream.html提供了类似的实现。
public int read() throws IOException {
try {
this.inputStream.read();
if (val != -1) {
return val;
} else {
this.inputStream.close();
return -1;
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Something is wrong!");
} finally {
try {
if (this.inputStream != null) {
this.inputStreamObj.close();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
如果this.inputStream
不为null,则必须使用finally块强制使用close()
。
您确定流没有释放吗? 因为当您(或休眠)通过BlobProxy实现释放调用Blob#free()
的blob时正在查看BlobProxy
代码,所以将执行InputStream#close()
,并且您的流应正确关闭。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.