简体   繁体   English

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

[英]How can you in Java list all files recursively in a folder that do not match an array of extensions?

I have a simple program that I am making that looks through a directory recursively and removes all files that do not match the files extensions chosen by the user. 我正在制作一个简单的程序,该程序递归遍历目录并删除所有与用户选择的文件扩展名不匹配的文件。 (essentially I am remaking a script that I wrote in PHP to help teach myself java) (本质上,我正在重新编写用PHP编写的脚本来帮助自学Java)

The method works fine except that it returns an array of files that match the array of extensions. 该方法工作正常,除了它返回与扩展名数组匹配的文件数组。 This would remove the wrong files. 这将删除错误的文件。 How can I return the files that do not match? 如何退回不匹配的文件?

I am using org.apache.commons.io.FileUtils with a string array to get the files: 我正在使用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;
    }
}

I have found examples that use just one file type eg ".txt" but cannot find one for an array. 我发现仅使用一种文件类型的示例,例如“ .txt”,但找不到用于数组的文件类型。 I would prefer to stick with org.apache.commons.io.FileUtils but I am willing to change my method. 我宁愿坚持使用org.apache.commons.io.FileUtils,但我愿意更改我的方法。

Use File.listFiles(), and use a java.io.FileFilter. 使用File.listFiles(),并使用java.io.FileFilter。 You write the filter to examine the filename and determine whether that file 'passes through' the filter. 您编写过滤器以检查文件名并确定该文件是否“通过”过滤器。 Instantiate your filter with the array of extensions you don't want or whatever. 用不需要的扩展名数组实例化过滤器。 You aren't using FileUtils, but you don't need anything outside of standard Java libraries. 您没有使用FileUtils,但是除了标准Java库之外,您不需要任何东西。

-- -

Edit after request for example 请求后进行编辑,例如

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;
  }
}

Now, look at the (various) signatures for listFiles in java.io.File. 现在,查看java.io.File中listFiles的(各种)签名。 One of them takes such a file filter. 其中之一采用了这种文件过滤器。 Only things that pass your file filter, ie, return true in the accept() method above, will be returned by listFiles() when given this filter. 当给定此过滤器时,只有通过文件过滤器的东西(即,在上面的accept()方法中返回true的东西)才会由listFiles()返回。

I agree with rcook's answer, but if you REALLY want to stick with FileUtils , here's an alternative: get all the files, then remove the ones that match the extensions. 我同意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;

Note this is a bit wasteful, involving two recursions through the filesystem. 请注意,这有点浪费,涉及通过文件系统进行两次递归。

You can get all the files in the directory and then just remove the files that you get for extensions that you dont want. 您可以获取目录中的所有文件,然后删除不需要的扩展名而获得的文件。

I use this to get files with particular extension: 我用它来获取具有特定扩展名的文件:

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

Here's the pure java alternative to using FileUtils , avoiding the efficiency problem of my other answer and supporting recursion. 这是使用FileUtils的纯Java替代方法,避免了我的其他答案的效率问题并支持递归。 This involves so much code I think I would favour the FileUtils solution. 这涉及很多代码,我想我更喜欢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;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM