我有一个要求,我需要根据文件的创建日期对每个单独的文件或文件夹进行压缩。因此,如果文件夹下的所有文件都符合业务标准,则需要压缩该文件夹,否则,我需要压缩各个文件。另外,如果所有同级文件夹都符合条件,则需要压缩父文件夹而不是子文件夹。
因此,例如,如果我具有如图所示的目录结构,并假设文件夹6下的所有文件均符合条件,但文件夹7下的所有文件均不符合条件,则将满足文件夹7下的条件的文件压缩,但是整个文件夹6都已压缩。如果文件夹6下的所有文件,文件夹7和文件夹3都符合条件,则如果文件夹2下的内容不符合条件,则将压缩文件夹3。如果文件夹2,文件夹3和文件夹1下的内容符合条件,则将文件夹1压缩。
我可以编写一种算法来压缩树中的最后一层,但是如果我需要爬到树上并检查父文件夹的详细信息并决定,我不确定如何继续进行。
答案 0 :(得分:0)
通常,我们会要求您到目前为止已编写的源代码,但是如果我正确理解的话,它就是递归的概念,而不是您要查找的代码本身,因此下面是解释递归概念的源代码。
还有其他方法可以做到这一点,但是这很简单。如我所见,您需要递归两次,因为叶子之间可能会相互影响(首先从下至上收集数据,然后从上至下收集数据)。
我在c:/ temp / zipper下构建了一个文件夹结构来测试代码。以“ m”开头的文件符合条件。希望这些注释和System.outs解释发生了什么。
public class Zipper {
private static String NO_ZIP_MESSAGE = "";
// private static String NO_ZIP_MESSAGE = " (no zip)";
public static void main(String[] args) {
new Zipper().go("C:/temp/zipper");
}
private void go(String startingFolderStr) {
MyFile startingFolder = new MyFile(new File(startingFolderStr), false);
boolean zipStartingFolder = recurse(startingFolder, "");
System.out.println("------------------ " + zipStartingFolder);
cleanup(startingFolder, "", false);
}
private boolean recurse(MyFile folder, String indent) {
// Go through the folder structure top-down and check if individual files meet the criteria, and also update zip
// flag for folders in "direct descendance".
System.out.println(indent + folder.file.getName());
boolean allSiblingsMeetCriteria = true;
for (File f : folder.file.listFiles()) {
MyFile mf = new MyFile(f, false);
folder.siblings.add(mf);
if (f.isFile()) {
boolean meetsCriteria = f.getName().startsWith("m");
mf.zip = !meetsCriteria;
allSiblingsMeetCriteria = allSiblingsMeetCriteria && meetsCriteria;
System.out.println(indent + " " + f.getName() + (meetsCriteria ? "" : " --> ZIP"));
} else if (f.isDirectory()) {
allSiblingsMeetCriteria = recurse(mf, indent + " ") && allSiblingsMeetCriteria;
}
}
folder.zip = allSiblingsMeetCriteria;
System.out.println(
indent + "... " + folder.file.getName() + (allSiblingsMeetCriteria ? " --> ZIP" : NO_ZIP_MESSAGE));
return allSiblingsMeetCriteria;
}
private void cleanup(MyFile folder, String indent, boolean parentIsZipped) {
// If we come to a folder with zip=true, all its subfolders have zip=true and all its subfiles have zip=false.
// Set parentIsZipped=true, and go thru and set all subfolders to zip=false (1). Ignore subfiles since they are
// already ok.
// If we come to a folder with zip=false (and we're not in a 'true flow' (comment above)), all subfiles should
// have zip=true (2), but we leave subfolders as is
System.out.println(indent + folder.file.getName() + (folder.zip ? " --> ZIP" : NO_ZIP_MESSAGE));
parentIsZipped = parentIsZipped || folder.zip;
for (MyFile mf : folder.siblings) {
if (mf.file.isFile()) {
if (!parentIsZipped) {
mf.zip = true; // (2)
}
System.out.println(indent + " " + mf.file.getName() + (mf.zip ? " --> ZIP" : NO_ZIP_MESSAGE));
} else if (mf.file.isDirectory()) {
if (parentIsZipped) {
mf.zip = false; // (1)
}
cleanup(mf, indent + " ", parentIsZipped);
}
}
}
private class MyFile {
File file;
boolean zip;
List<MyFile> siblings;
public MyFile(File file, boolean zip) {
this.file = file;
this.zip = zip;
siblings = new ArrayList<>();
}
}
}