【问题标题】:Creating a List of BufferedReaders创建 BufferedReaders 列表
【发布时间】:2011-08-27 16:14:38
【问题描述】:

我想要一个返回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;
}

这是否会严重浪费资源?

所有这些流是否会在创建时打开并保持如此状态从而占用系统资源?

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

【问题讨论】:

  • 为什么不在需要的时候创建阅读器?
  • @Kevin 我简化了任务,我需要处理混合了 url 的文件名以及带有文件名过滤器的目录等。我想将所有这些隐藏在一个单独的方法中,并且只有一个列表读者在最后。
  • 你能在一个类中“隐藏”混合的 url 并将其提供给工厂或其他返回适当读取器实例的类吗?
  • @Kevin 我可以,但我想看看我是否可以先列出读者名单,因为这对我来说是一个更简单的解决方案。

标签: java stream io


【解决方案1】:

是的,FileInputStream 的构造函数在其构造函数中调用 open()open() 是一个本地方法,它很可能会为文件保留一个文件描述符。

与其立即返回一个 BufferedReaders 列表,不如返回一个将根据需要打开底层流的东西的列表?您可以创建一个保存文件名的类,并在调用时简单地打开资源。

【讨论】:

    【解决方案2】:

    我很确定这是个坏主意。您冒着消耗所有可用文件描述符的风险,如果您不想从中读取文件,则打开读取器是没有意义的。

    如果要从文件中读取,请打开阅读器,从文件中读取,然后关闭阅读器。然后,对下一个要读取的文件执行相同操作。

    如果您想要一个独特的抽象来从各种来源(URL、文件等)读取,那么创建您自己的Source 接口和多个实现来包装要从中读取的资源(URLSource、FileSource 等)。 )。仅在从您的 Source 实例读取时打开包装资源上的实际阅读器。

    【讨论】:

      【解决方案3】:

      是的,这些流将在创建后立即打开

      避免这种情况的好方法是创建一个仅在第一次读取时初始化 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()
      
      }
      

      【讨论】:

        猜你喜欢
        • 2014-04-03
        • 1970-01-01
        • 2020-03-13
        • 1970-01-01
        • 2017-10-09
        • 2021-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多