我有一个类,一方面,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 );
}
}
但是,我对此也非常谨慎,因为它使调用者有责任关闭此流。我可以通过哪些方式潜在地避免这个问题?
取决于为什么这是您眼中的问题。如果您绝对必须返回一个InputStream
并且有问题的文件不是太大,您可以将整个文件缓冲到一个字节数组中,关闭原始流和return new ByteArrayInputStream(buf)
. 关闭 aByteArrayInputStream
不是必需的(实际上没有效果)。
但是,如果返回 an “感觉正确” InputStream
,那么调用者应该期待anInputStream
以及随之而来的所有事情,包括完成后关闭流的必要性,这难道没有意义吗?
回归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()
装饰。
实际上,如果不了解有关课程的更多详细信息,您将无能为力。您可以通过 MyClass 中的方法提供文件处理(这需要知道文件内容的含义)并在流为空时关闭流。但除此之外,该类的用户对该对象负责,您无法真正避免这种情况。如果没有析构函数的能力,就像在 C++ 中一样,你不能对任何离开你的类范围的对象负 100% 的责任。
您可以做的是close()
在您的类上放置一个方法来清理所有打开的文件处理程序、连接等,并要求该类的用户负责调用close()
. 有关如何使用该方法跟踪调用者是否正确关闭您的课程的一些讨论,请参阅此问题。finalize
...因为它使调用者有责任关闭此流。
是的,调用者负责处理返回的流的关闭操作。由于您的方法无法跟踪其返回的内容,因此该任务完全属于调用者。这种情况和使用异常有一个类比。开发人员使用异常是因为 API 作者不能总是控制他们呈现给我们的内容。我们必须小心,例如当有可能将数字除以零时。