我有一个课程,一方面,从公共方法返回InputStream
感觉是正确的,例如
public class MyClass {
private File _file;
...
public InputStream getInputStream() {
return new FileInputStream( _file );
}
}
但是,我对这样做也非常谨慎,因为它会让调用者有责任关闭此流。我有什么方法可以避免这个问题?
答案 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作者无法始终控制他们向我们呈现的内容。我们必须小心,例如当有可能将数字除以零时。