创建BufferedReaders列表

时间:2011-08-27 16:14:39

标签: java stream io

我想有一个方法可以返回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;
}

这会是资源的主要浪费吗?

所有这些流是否会在创建时打开并保持系统资源?

如果是,我是否可以在“被动”模式下创建这些阅读器而无需实际打开流,或者是否有其他解决方法(因此我可以安全地构建包含数千个阅读器的列表)?

3 个答案:

答案 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()

}
相关问题