如何在 java 中 'walk' 具有多个文件扩展名的多个目录?

How to 'walk' multiple directories, with multiple file extensions, in java?

这是我的实际代码,效果很好:
String sHomeDir 是我开始扫描的唯一文件夹
String sExt 是搜索的唯一扩展

try (Stream<Path> walk = Files.walk(Paths.get(sHomeDir)))
{
    List<String> result = walk.map(x -> x.toString())
        .filter(f -> f.endsWith(sExt)).collect(Collectors.toList());
    ...
} catch (IOException e) {
   e.printStackTrace();
}

是否可以重写,以便使用:
- 要扫描的多个文件夹(带子树)
- 要搜索的多个文件扩展名

要处理多个目录,您可以将它们流式传输并将它们平面映射到单个路径流。 要处理多个扩展名,您只需要针对所有扩展名检查文件:

public static List<String> multiWalk
    (Collection<String> directories, Collection<String> extensions) {

    return directories.stream()
                      .flatMap(d -> {
                          try {
                              return Files.walk(Paths.get(d));
                          } catch (IOException e) {
                              return Stream.empty();
                          }
                      })
                      .map(Object::toString)
                      .filter(f -> extensions.stream().anyMatch(f::endsWith))
                      .collect(Collectors.toList());
}

我想使用与“File.list()”-方法一起使用的 FilenameFilter。我找到了样本 here.

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

/**
 * 
 * @see: 
 * 
 * <h3>setup filter like:</h3>
 * private static final ExtensionsFilenameFilter IMAGE_FILTER = <br/>
      new ExtensionsFilenameFilter(".png", ".jpg", ".bmp"); 
 * 
 */
public class ExtensionsFilenameFilter implements FilenameFilter {
    
    private char[][] extensions;

    public ExtensionsFilenameFilter(String... extensions)
    {
        int length = extensions.length;
        this.extensions = new char[length][];
        for (String s : extensions)
        {
            this.extensions[--length] = s.toCharArray();
        }
    }

    @Override
    public boolean accept(File dir, String name) {
        char[] path = name.toCharArray();
        for (char[] extension : extensions)
        {
            if (extension.length > path.length)
            {
                continue;
            }
            int pStart = path.length - 1;
            int eStart = extension.length - 1;
            boolean success = true;
            for (int i = 0; i <= eStart; i++)
            {
                if ((path[pStart - i] | 0x20) != (extension[eStart - i] | 0x20))
                {
                    success = false;
                    break;
                }
            }
            if (success)
                return true;
        }
        return false;
    }

}

然后我通过以下方式遍历根路径下的所有路径:

public void walkList(String path) throws IOException {
    List<String> imagefiles = new ArrayList<>();
    Files.walk(Paths.get(path))
    .filter(Files::isDirectory)
    .map(walkPath -> {
        List<String> pathnames = new ArrayList<>();
        List<String> filenames = Arrays.asList(walkPath.toFile().list(new ExtensionsFilenameFilter("jpg", "tif", "bmp")));
        filenames.forEach(fn -> {
            pathnames.add(String.format("%s/%s", walkPath.toFile().toString(), fn));
        });
        return pathnames;
    })
    .forEach(imagefiles::addAll);

    imagefiles.forEach(System.out::println);
}