Java复制除某些内部文件之外的文件夹

Ste*_*ano 5 java directory copy

我有一个这种结构的文件夹

mainFolder

   --Sub1  
         --File .scl
         --File .awl
         --Other files
   --Sub2  
         --Files
   --Sub3
   --Sub4
Run Code Online (Sandbox Code Playgroud)

我想将它复制到另一个位置,但我希望避免Sub3和(取决于情况)来自Sub1的一些文件

这是我到目前为止所做的摘录:

FileUtils.copyDirectory(srcDir, dstDir, new FileFilter() {
        public boolean accept(File pathname) {
            // We don't want 'Sub3' folder to be imported
            // + look at the settings to decide if some format needs to be
            // excluded
            String[] ignoreList= new String[]{
                    !Settings.getSiemensOptionAWL() ? ".awl":"uselessStringWilNeverBeFound",
                    !Settings.getSiemensOptionSCL() ? ".scl":"uselessStringWilNeverBeFound",
                    "Sub3"
            };

            return !(ignoreFile(pathname, ignoreList) && pathname
                    .isDirectory());
        }
    }, true);


    public static boolean ignoreFile(File file, String[] ignoreList) {
        for (final String ignoreStr : ignoreList)
            if (file.getAbsolutePath().contains(ignoreStr))
                return true;
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

显然它接缝起作用了.但我认为这是一个非常难看的解决方案....有谁知道更好的方法?

PS:当然,Settings.getSiemensOptionAWL()只是布尔函数taht返回我的决定

Pet*_*ter 5

这里建议的其他选项都很好,但是另一种选择是将多个更简单的文件过滤器嵌套在一起(当然,这可能有点过头了!)

public class FailFastFileFilter implements FileFilter {
    protected final List<FileFilter> children = new ArrayList<FileFilter>();

    public FailFastFileFilter(FileFilter... filters) {
        for (FileFilter filter: filters) {
            if (filter != null)
                this.filters.add(filter);
        }       
    }

    public boolean accept(File pathname) {
        for (FileFilter filter: this.filters) {
            if (!filter.accept(pathname)) {
                return false; // fail on the first reject
            }
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后简单地将简短的 FileFilters 组合起来用于 Sub3 情况、.scl 和 .awl 情况。我上面显示的示例 FailFastFileFilter 允许您指定 null 作为过滤器之一(因此您可以使用内联 if 语句来确定是否应用特定的 FileFilters)

为了完整起见,以下是我如何实现 Sub1 情况和 Sub3 情况的子过滤器的一般概念。

首先,过滤器排除目录中具有特定扩展名的文件:

public class ExcludeExtensionInDirFileFilter implements FileFilter {
    protected final String parentFolder;
    protected final String extension;

    public ExtensionFileFilter(String parentFolder, String extension) {
        this.parentFolder = parentFolder;
        this.extension = extension.toLowerCase();
    }

    public boolean accept(File file) {
        if (!file.isDirectory() && file.getParentFile().getName().equalsIgnoreCase(parentFolder))
            return !file.getAbsolutePath().toLowerCase().endsWith(extension);
        else
            return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后排除目录:

public class ExcludeDirFileFilter implements FileFilter {
    protected final String name;

    public ExcludeDirFileFilter(String name) {
        this.name = name.toLowerCase();
    }

    public boolean accept(File file) {
        if (file.isDirectory() && file.getName().equalsIgnoreCase(name))
            return false;
        else
            return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

设置 FailFastFileFilter 将类似于:

FileFilter filters = new FailFastFileFilter(
    new ExcludeDirFileFilter("Sub3"), // always exclude Sub3
    (!Settings.getSiemensOptionAWL() ? new ExcludeExtensionInDirFileFilter("Sub1",".awl"), null), // Exclude Sub1/*.awl if desired
    (!Settings.getSiemensOptionSCL() ? new ExcludeExtensionInDirFileFilter("Sub1",".scl"), null) // Exclude Sub1/*.scl if desired
);

FileUtils.copyDirectory(srcDir, dstDir, filters);
Run Code Online (Sandbox Code Playgroud)