递归列出所有扩展名为 .txt 的文件

Posted

技术标签:

【中文标题】递归列出所有扩展名为 .txt 的文件【英文标题】:Listing all files with a .txt extension recursively 【发布时间】:2019-06-19 20:34:39 【问题描述】:

我正在尝试递归搜索目录并列出找到的所有 .txt 文件。这是我的代码:

private static void listFilesForFolder(File folder) throws FileNotFoundException 
for (final File fileEntry : folder.listFiles()) 
        if (fileEntry.isDirectory()) 
            listFilesForFolder(fileEntry);
         else 
            System.out.println(Arrays.toString(fileEntry.listFiles(new FileFilter() 
                @Override
                public boolean accept(File pathname) 
                    return pathname.getName().endsWith(".txt");
                
            )));
        
    

我正在使用 FileFilter 打印出所有 .txt 文件,但它打印出 null 代替。有谁知道为什么会这样?

【问题讨论】:

在您的代码中 listFilesForFolder(fileEntry); 不是递归调用。因为您展示的这个方法没有将File 作为参数。 很好,但我很糟糕。我编辑了帖子,但问题仍然存在。你知道为什么吗? fileEntry不是一个目录时,你认为fileEntry.listFiles(...)会做什么,你为什么相信? --- 根据javadoc:“如果这个抽象路径名不代表一个目录,那么这个方法返回null。这就是它打印 null 的原因。 Walking the file system 可能是更好的起点 【参考方案1】:

我认为您可以简单地使用 if 语句,而不是在 else 块中使用 FileFilter。因为在这个else 块中,你总是有一个文件(不是目录)。看看以下更改是否适合您。

private static void listFilesForFolder(File folder) throws FileNotFoundException

  for (final File fileEntry : folder.listFiles()) 
    if (fileEntry.isDirectory()) 
      listFilesForFolder(fileEntry);
     else 
      if (fileEntry.getPath().toLowerCase().endsWith(".txt")) 
        System.out.println(fileEntry.getPath());
      
      /*System.out.println(Arrays.toString(fileEntry.listFiles(new FileFilter() 
        @Override
        public boolean accept(File pathname) 
          return pathname.getName().endsWith(".txt");
        
      )));*/
    
  

编辑: 如果你真的想使用FileFilter 来做这件事,你可以这样做:

private static void listFilesForFolder2(File folder) throws FileNotFoundException

  File[] textFiles = folder.listFiles(new FileFilter() 
    @Override
    public boolean accept(File pathname) 
      return pathname.isFile() && pathname.getName().toLowerCase().endsWith(".txt");
    
  );
  if (textFiles != null) 
    for (File f : textFiles) 
      System.out.println(f.getPath());
    
  

  for (final File fileEntry : folder.listFiles()) 
    if (fileEntry.isDirectory()) 
      listFilesForFolder2(fileEntry);
    
  

【讨论】:

这是一个很好的解决方案!但是你知道如何在函数中加入 FileFilter 吗? 请记住,文件扩展名也可以是大写字母。 @DevilsHnd,谢谢。我添加了toLowerCase() 来处理这个问题。【参考方案2】:

只有当file对象是Directory对象时,file.listFiles()方法才返回String[],如果fileFile对象,它将返回null。你可以像这样修改你的代码:

for (final File fileEntry : folder.listFiles()) 
    if (fileEntry.isDirectory()) 
        listFilesForFolder(fileEntry);
     else 
        if (fileEntry.getName().endsWith(".txt")) 
            System.out.println(fileEntry.getName());
        
    

如果你可以使用 apache commons-io,那么使用IOFileFilter 来过滤你想要的东西会很容易:

    FileUtils.listFiles(folder, new IOFileFilter() 
        @Override
        public boolean accept(File file) 
            return file.getName().endsWith(".txt");
        

        @Override
        public boolean accept(File file, String s) 
            return true;
        
    , new IOFileFilter() 
        @Override
        public boolean accept(File file) 
            return true;
        

        @Override
        public boolean accept(File file, String s) 
            return true;
        
    ).stream().forEach(file -> System.out.println(file.getName()));

【讨论】:

以上是关于递归列出所有扩展名为 .txt 的文件的主要内容,如果未能解决你的问题,请参考以下文章

递归批量重命名文件扩展名(Windows批处理)

在 Python 中查找扩展名为 .txt 的目录中的所有文件

列出文件夹下所有的文本文件名python

使用批处理文件在目录下递归删除所有特定类型(扩展名)的文件

如何在 Visual Studio Code 中列出/搜索特定类型的所有文件

如何检查目录中是不是存在扩展名为 .txt 的文件?