繁体   English   中英

InputStream包装器,读取完成后将关闭流

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM