从公共方法返回InputStream

时间:2012-11-16 16:32:32

标签: java io inputstream

我有一个课程,一方面,从公共方法返回InputStream感觉是正确的,例如

public class MyClass {

    private File _file;

    ...

    public InputStream getInputStream() {
        return new FileInputStream( _file );
    }
}

但是,我对这样做也非常谨慎,因为它会让调用者有责任关闭此流。我有什么方法可以避免这个问题?

4 个答案:

答案 0 :(得分:7)

取决于为什么这是你眼中的问题。如果绝对必须返回InputStream并且有问题的文件不是太大,则可以将整个文件缓冲为字节数组,关闭原始流和return new ByteArrayInputStream(buf)。关闭ByteArrayInputStream不是必要的(实际上没有效果)。

但是,如果返回InputStream“感觉正确”,那么调用者应该期待 InputStream没有意义,并且所有这一切都与它,包括完成后关闭流的必要性?

答案 1 :(得分:5)

返回InputStream本质上不是一件坏事。现在,如果您希望调用者访问数据而不负责关闭资源,您可以这样做:

interface InputReader {
    void readInput(InputStream is);
}
public class MyClass {
    void feed(InputReader ir){
       try(InputStream is=new FileInputStream( _file )){
          ir.readInput(is);
       }
    }
}

调用者指定InputReader的实例,该实例将接收可关闭的资源作为参数,并且不再负责关闭它。

MyClass myClass = ... ; //Get the instance
myClass.feed( new InputReader() {
    @Override
    void readInput(InputStream is){
       ... ; // Use at will without closing
    }
});

在将InputStream传递给InputReader之前应考虑装饰.close(),以便{{1}}抛出异常。

答案 2 :(得分:2)

实际上,如果不了解关于课程的更多细节,你就无能为力。您可以通过MyClass中的方法提供文件处理(这需要知道文件内容的含义)并在流为空时关闭流。除此之外,该类的用户负责此对象,您无法真正避免这种情况。如果没有析构函数的功能,就像在C ++中一样,对于任何让你离开课堂范围的对象,你都不能100%负责。

致电close()。有关如何使用close()方法跟踪呼叫者是否正确关闭班级的一些讨论,请参阅this question

答案 3 :(得分:1)

  

...因为它将责任放在调用者身上以关闭此流。

是的,调用者负责处理返回的流的关闭操作。 由于您的方法无法跟踪其返回的内容,此任务完全属于调用者。这种情况与使用例外之间有类比。开发人员使用异常,因为API作者无法始终控制他们向我们呈现的内容。我们必须小心,例如当有可能将数字除以零时。