Java 从公共方法返回InputStream

Java 从公共方法返回InputStream,java,io,inputstream,Java,Io,Inputstream,我有一个类,一方面,它感觉从公共方法返回InputStream是正确的,例如 public class MyClass { private File _file; ... public InputStream getInputStream() { return new FileInputStream( _file ); } } 但是,我对这样做也非常谨慎,因为这会让调用者承担关闭此流的责任。我有哪些方法可以避免此问题 …因为它让调用方有责任

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

public class MyClass {

    private File _file;

    ...

    public InputStream getInputStream() {
        return new FileInputStream( _file );
    }
}
但是,我对这样做也非常谨慎,因为这会让调用者承担关闭此流的责任。我有哪些方法可以避免此问题

…因为它让调用方有责任关闭此流

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

实际上,如果不了解更多有关该类的详细信息,您将无能为力。您可以通过MyClass中的方法提供文件处理(这需要知道文件内容的含义),并在流为空时关闭流。除此之外,类的用户负责这个对象,您不能真正避免。没有析构函数的能力,如C++,你不能对任何你离开类的范围负责的对象负责。


您可以在类上放置一个
close()
方法,该方法清除所有打开的文件处理程序、连接等,并要求类的用户负责调用
close()
。有关如何使用
finalize
方法跟踪调用方是否正确关闭类的讨论,请参阅

这取决于为什么这是你眼中的问题。如果您必须返回一个
InputStream
,并且所涉及的文件不是太大,您可以将整个文件缓冲到一个字节数组中,关闭原始流并
返回新的ByteArrayInputStream(buf)
。通过tearrayinputstream关闭
是不必要的(实际上没有效果)


然而,如果返回一个
InputStream
“感觉正确”,那么调用者应该期待一个
InputStream
,以及随之而来的所有事情,包括在完成时关闭流的必要性,这难道没有意义吗?

返回
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
    }
});

应考虑将<代码>输入流< /代码>传递给<代码> InputReader < /代码>,以便<>代码>关闭()<代码/>抛出和异常。

我不认为这是个问题。Java API(例如,
ServletResponse.getOutputStream()
)中已经实现了这一点。虽然我非常喜欢尝试制作一个能够降低出错可能性的API,但您可以从使用它的人那里得到一个最低限度的期望。我认为关闭
InputStream
s就是其中之一——如果他们不记得这样做,那只能怪他们自己。