我想有一个方法可以返回BufferedReader
个对象的列表(例如,对于目录中的所有文件):
private List<BufferedReader> getInputReaders(List<String> filenames) {
List<BufferedReader> result = new ArrayList<BufferedReader>();
for(String filename : filenames)
result.add(new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8")));
}
return result;
}
这会是资源的主要浪费吗?
所有这些流是否会在创建时打开并保持系统资源?
如果是,我是否可以在“被动”模式下创建这些阅读器而无需实际打开流,或者是否有其他解决方法(因此我可以安全地构建包含数千个阅读器的列表)?
答案 0 :(得分:1)
是的,FileInputStream
的构造函数在其构造函数中调用open()
。 open()
是一种本机方法,很可能会保留文件的文件描述符。
为什么不返回一个将根据需要打开底层流的内容列表,而不是立即返回BufferedReaders列表?您可以创建一个保留文件名的类,并在调用时打开资源。
答案 1 :(得分:1)
我很确定这是一个坏主意。您冒着使用所有可用文件描述符的风险,如果您不想从中读取文件,则无需打开读取器。
如果要从文件中读取,请打开阅读器,从文件中读取,然后关闭阅读器。然后,对下一个要读取的文件执行相同操作。
如果你想从各种来源(URL,文件等)中读取一个独特的抽象,那么创建你自己的Source
接口,以及将资源包装起来的多个实现(URLSource,FileSource,等等。)。在从Source
实例中读取时,仅打开包装资源上的实际读者。
答案 2 :(得分:1)
是的,这些流将在创建后立即打开
避免这种情况的好方法是创建一个只在第一次读取时初始化Reader的LazyReader类
public class LazyReader extends Reader{
String fileName;
Reader reader=null;
public LazyReader(String filename){
super();
this.fileName=fileName;
}
private void init(){
if(reader==null)
reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8"));
}
public int read(char[] cbuf, int off, int len){
init();
return reader.read(cbuff, off,len);
}
public int close(){
init();
reader.close();
}
//if you want marking you should also implement mark(int), reset() and markSupported()
}