我有一个具有此结构的文件夹
mainFolder
--Sub1
--File .scl
--File .awl
--Other files
--Sub2
--Files
--Sub3
--Sub4
我想将它复制到另一个位置,但我希望避免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;
}
显然它接缝起作用了。但我认为这是一个非常难看的解决方案.... 有谁知道更好的方法?
P.S: 当然,Settings.getSiemensOptionAWL()只是布尔函数taht返回我的决定
答案 0 :(得分:4)
这里建议的其他选项都很好,但是另一个选择是将多个更简单的FileFilter嵌套在一起(当然,这可能有点过头了!)
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;
}
}
然后简单地为Sub3案例,.scl和.awl案例组合简短,简洁的FileFilters。我上面显示的示例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;
}
}
然后排除目录:
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;
}
}
设置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);
答案 1 :(得分:3)
我认为丑陋来自于引入ignoreFile()
,它必然会丢失一些有用的信息(哪些字符串实际上很重要,哪些字符串是文件扩展名等)。此外,该数组将为每个人创建您的层次结构中的文件,这是非常低效的。考虑这样的事情,而不是:
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 name = pathname.getName();
if (!Settings.getSiemensOptionAWL() && name.endsWith(".awl"))
return false;
if (!Settings.getSiemensOptionSCL() && name.endsWith(".scl"))
return false;
return !(name.equals("Sub3") && pathname.isDirectory());
}
}, true);
答案 2 :(得分:1)
这些字符串是否固定在石头上?也许像是
new FileFilter() {
public boolean accept(File pathname) {
String path = pathname.getAbsolutePath().toLowerCase();
return (!pathname.isDirectory() || path.endsWith("sub3")) &&
(!Settings.getSiemensOptionAWL() && path.endsWith(".awl")) &&
(!Settings.getSiemensOptionSCL() && path.endsWith(".scl"));
}
}
答案 3 :(得分:-1)
看起来很干净。只是不要将所有内容直接放在调用代码中,这样您就不必一直查看它。创建自己的CopySubDir类,隐藏所有这些代码,并提供一个简单易懂的接口。然后调用代码看起来很干净。