在Java中,如何递归地列出文件夹中与扩展名数组不匹配的所有文件?

在Java中,如何递归地列出文件夹中与扩展名数组不匹配的所有文件?,java,file,Java,File,我有一个我正在制作的简单程序,它递归地查看目录并删除所有与用户选择的文件扩展名不匹配的文件。(本质上,我正在重新编写一个用PHP编写的脚本,以帮助自学java) 除了返回与扩展名数组匹配的文件数组外,该方法工作正常。这将删除错误的文件。如何返回不匹配的文件 我正在使用org.apache.commons.io.FileUtils和字符串数组来获取文件: import java.io.File; import java.util.List; import java.io.IOException;

我有一个我正在制作的简单程序,它递归地查看目录并删除所有与用户选择的文件扩展名不匹配的文件。(本质上,我正在重新编写一个用PHP编写的脚本,以帮助自学java)

除了返回与扩展名数组匹配的文件数组外,该方法工作正常。这将删除错误的文件。如何返回不匹配的文件

我正在使用org.apache.commons.io.FileUtils和字符串数组来获取文件:

import java.io.File;
import java.util.List;
import java.io.IOException;
import org.apache.commons.io.FileUtils;

public class Recurse {
// The method that takes a directory path (file object called folder) and a string of extensions
    public static List<File> getFiles(final File folder, String[] extensions) throws IOException{

    List<File> fileList = (List<File>) FileUtils.listFiles(folder, extensions, true);

    return fileList;
    }
}
导入java.io.File;
导入java.util.List;
导入java.io.IOException;
导入org.apache.commons.io.FileUtils;
公共类递归{
//采用目录路径(称为文件夹的文件对象)和扩展名字符串的方法
公共静态列表getFiles(最终文件夹,字符串[]扩展名)引发IOException{
List fileList=(List)FileUtils.listFiles(文件夹,扩展名,true);
返回文件列表;
}
}
我发现一些示例只使用一种文件类型,例如“.txt”,但无法为数组找到一种。我更愿意使用org.apache.commons.io.FileUtils,但我愿意改变我的方法。

使用File.listFiles(),并使用java.io.FileFilter。编写筛选器以检查文件名并确定该文件是否“通过”筛选器。用你不想要的扩展数组或其他什么实例化你的过滤器。您没有使用FileUtils,但不需要标准Java库之外的任何东西

--

例如,请求后编辑

public class NotTheseExtensions implements java.io.FileFilter
{
  private ArrayList<String> extensions;

  public NotTheseExtensions(ArrayList<String> extensions)
  {
    this.extensions = extensions;
  }

  public boolean accept(String filename)
  {
    boolean result = true;
    boolean inList = false;  // set this in your own logic

    // logic to get the extension from the filename and look to see if it is
    // in your list -- hopefully I don't have to write that for you as well.
    if (inList) { result = false; }

    return result;
  }
}
公共类NotTheseExtensions实现java.io.FileFilter
{
私有ArrayList扩展;
公共扩展(ArrayList扩展)
{
this.extensions=扩展;
}
公共布尔接受(字符串文件名)
{
布尔结果=真;
boolean inList=false;//在您自己的逻辑中设置
//逻辑从文件名中获取扩展名,并查看是否正确
//在你的列表中——希望我也不必为你写。
如果(inList){result=false;}
返回结果;
}
}

现在,看看java.io.File中列表文件的(各种)签名。其中一个采用了这样的文件过滤器。当给定此筛选器时,listFiles()将仅返回通过您的文件筛选器的内容,即在上面的accept()方法中返回true。

您可以获取目录中的所有文件,然后仅删除您不想要的扩展名的文件

我使用它来获取具有特定扩展名的文件:

File dir = new File(fileDir);
FileFilter fileFilter = new WildcardFileFilter("*.txt");
File[] files = dir.listFiles(fileFilter);

我同意rcook的回答,但是如果你真的想坚持使用
FileUtils
,这里有一个替代方法:获取所有文件,然后删除与扩展名匹配的文件

List<File> all = (List<File>) FileUtils.listFiles(folder, null, true);
List<File> unwanted = (List<File>) FileUtils.listFiles(folder, extensions, true);
all.removeAll(unwanted);
return all;
List all=(List)FileUtils.listFiles(folder,null,true);
List UNHERED=(List)FileUtils.listFiles(文件夹,扩展名,true);
全部。移除所有(不需要的);
全部归还;

注意,这有点浪费,涉及通过文件系统的两个递归。

这里是使用
FileUtils
的纯java替代方案,避免了我的另一个答案的效率问题并支持递归。这涉及到太多的代码,我想我更喜欢
FileUtils
解决方案

public void myMethod() {
    List<File> files = recursiveList(folder, new String[] { "jpg", "png" });
    // ... do something ...
}

private List<File> recursiveList(File folder, String[] rejectedExtensions) {
    List<File> files = new ArrayList<File>();
    for (File subfolder : folder.listFiles(new DirectoryFilter())) {
        files.addAll(recursiveList(subfolder, rejectedExtensions));
    }
    files.addAll(Arrays.asList(folder.listFiles(new ExtensionFilter(rejectedExtensions))));
    return files;
}

private class DirectoryFilter implements FileFilter {
    @Override
    public boolean accept(File file) {
        return file.isDirectory();
    }
}

private class ExtensionFilter implements FileFilter {

    private final String[] rejectedExtensions;

    public ExtensionFilter(String[] rejectedExtensions) {
        this.rejectedExtensions = rejectedExtensions;
    }

    @Override
    public boolean accept(File file) {
        if (file.isDirectory()) {
            return false;
        }
        String name = file.getName();
        for (String rejectedExtension : rejectedExtensions) {
            if (name.endsWith(rejectedExtension)) {
                return false;
            }
        }
        return true;
    }

}
public void myMethod(){
列表文件=递归列表(文件夹,新字符串[]{“jpg”,“png”});
//…做点什么。。。
}
私有列表递归列表(文件夹,字符串[]拒绝扩展){
列表文件=新的ArrayList();
对于(文件子文件夹:folder.listFiles(新的DirectoryFilter())){
addAll(递归列表(子文件夹,rejectedExtensions));
}
files.addAll(Arrays.asList(folder.listFiles(新扩展过滤器(rejectedExtensions)));
归还文件;
}
私有类DirectoryFilter实现FileFilter{
@凌驾
公共布尔接受(文件){
返回文件.isDirectory();
}
}
私有类ExtensionFilter实现FileFilter{
私有最终字符串[]拒绝扩展;
公共扩展筛选器(字符串[]拒绝扩展){
this.rejectedExtensions=rejectedExtensions;
}
@凌驾
公共布尔接受(文件){
if(file.isDirectory()){
返回false;
}
字符串名称=file.getName();
for(字符串rejectedExtension:rejectedExtensions){
if(name.endsWith(rejectedExtension)){
返回false;
}
}
返回true;
}
}

等等,为什么要按扩展名排除文件?你能用
FileUtils
找到所有文件,然后自己测试扩展名吗?这基本上就是我要找的,但我不知道如何使用Java。如果你有一个很好的代码示例,这与我想要的非常接近,只是我的问题是我不知道文件夹中所有可能的扩展名。你不需要知道扩展名。您可以获得所有文件的列表,而不考虑扩展名。然后从列表中删除不需要扩展名的文件。您可以通过以下方式获得它:List results=new ArrayList();File[]files=新文件(“/path/to/the/directory”).listFiles();对于(File:files){if(File.isFile()){results.add(File.getName());}}}您有一个小例子来说明我是如何做到这一点的吗?这是最好的纯Java方法,但问题中的代码会通过子目录进行递归搜索,纯Java中的代码要比使用FileUtils多得多。这正是我想要的。但我确实同意,循环两次是浪费。你有一个更“正确”的方法来实现这一点的例子吗?可能会有所不同。php脚本最初是为了在基于linux的托管服务器上从数百个目录和数千个文件中删除所有非映像文件而编写的。然后它就从那里进化而来