【问题标题】:Find first file in directory with Java用Java查找目录中的第一个文件
【发布时间】:2011-10-29 14:43:08
【问题描述】:

我有某种批处理程序,它应该从目录中提取文件并对其进行处理。

因为这个程序应该:

  • 在 JDK 5 上运行,
  • 要小(没有外部库)
  • 而且速度很快! (一声巨响)

...什么是从目录中只选择一个文件的最佳方法 - 不使用 File.list()(可能是数百个文件)?

【问题讨论】:

  • 你想选择一个命名的文件/目录还是任何文件?此外,在处理完该文件后,您是继续处理其他文件还是退出程序?
  • 所以要明确一点,是需要从目录中获取文件(任意文件)还是只想知道目录中是否包含文件?
  • 只是任何文件,第一个找到的文件 - 程序应该在目录中有文件时执行此操作(文件不断添加);就是不想每次都把文件夹里的所有文件都列出来,好像效率很低……
  • 在 Java 1.5 上没有好的解决方案,您可以使用过滤器只获取 1 个文件,但是 java 只会返回一个文件但无论如何都会解析所有文件。
  • 文件是什么让它成为“第一”?最早的创作日期?按名称排序的第一名?体积最小?顺便说一句 - 您是否测量过列出 100 个文件所需的时间,您是否只是在进行这种过早的优化?

标签: java io java-io


【解决方案1】:

从您所说的看来,您希望处理目录中的每个文件一次(包括添加到目录中的文件)。您可以执行以下操作:在添加文件时生成通知的目录上设置监视器。然后,您处理收到通知的每个文件。由于您使用 JDK 5 ,我建议使用 jpathwatch 。请注意,在尝试处理文件之前,您需要确保文件写入已完成。在启动监视器以确保您将处理每个新文件后,请一次性使用文件列表来处理当前内容。

【讨论】:

    【解决方案2】:

    如果看一下 FileSystem 类,它归结为用于文件系统访问,只有 list 方法,所以在“纯”JAVA 中似乎没有其他方法可以选择文件,而不是在 String 中列出它们数组。

    【讨论】:

      【解决方案3】:

      编辑:我的实现使用了 .list() 正如你所说的那样,但它可能仍然具有一些价值:)

      如果你看一下 File 实现 public String[] list() 方法的开销似乎比 File[] listFiles() 少。所以最快的应该是

      String[] ss = myDir.list();
      File toProcess = null;
      for(int i = o ; i< ss.length ; i++){
       toProcess = new File(myDir.list()[i], myDir));
       if(toProcess.isFile())break;
      }
      

      来自 File.class

      public File[] listFiles() {
      String[] ss = list();
      if (ss == null) return null;
      int n = ss.length;
      File[] fs = new File[n];
      for (int i = 0; i < n; i++) {
          fs[i] = new File(ss[i], this);
      }
      return fs;
      }
      

      【讨论】:

        【解决方案4】:

        在 Java 1.5 上没有很好的解决方案,您可以使用过滤器仅获取 1 个文件,但 Java 只会返回一个文件,但无论如何都会解析所有文件。如果您不需要实际的文件对象,您可以尝试类似Runtime.getRuntime().exec("dir")\n 上拆分返回的字符串并打印出第一行:-P

        【讨论】:

          【解决方案5】:

          使用FileFilter(或FilenameFilter)写成只接受一次,例如:

          File dir = new File("/some/dir");
          File[] files = dir.listFiles(new FileFilter() {
              boolean first = true;
              public boolean accept(final File pathname) {
                  if (first) {
                      first = false;
                      return true;
                  }
                  return false;
              }
          });
          

          【讨论】:

          • 确实如此,但它确实避免了创建和返回整个 File 或文件名对象数组的开销。
          【解决方案6】:

          在 Java 7 中,您可以使用 DirectoryStream,但在 Java 5 中,获取目录条目的唯一方法是 list()listFiles()

          请注意,列出包含数百个文件的目录并不理想,但与处理其中一个文件相比,仍然可能没什么大不了的。但是一旦目录包含数千个文件,它可能会开始出现问题。

          【讨论】:

          • 您关于大目录的观点非常正确。但是这些会导致除了 Java 之外的许多事情的问题。最好的方法是不要将大量文件放在一个目录中。
          • 最佳答案,简短而甜蜜:)
          • DirectoryStream 是接口,我们不能将它用于任何工作,包括获取文件。
          猜你喜欢
          • 1970-01-01
          • 2013-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-14
          • 2021-03-06
          • 2017-07-04
          • 1970-01-01
          相关资源
          最近更新 更多