根据业务准则压缩文件夹/文件

时间:2019-07-15 23:21:11

标签: java algorithm recursion data-structures

我有一个要求,我需要根据文件的创建日期对每个单独的文件或文件夹进行压缩。因此,如果文件夹下的所有文件都符合业务标准,则需要压缩该文件夹,否则,我需要压缩各个文件。另外,如果所有同级文件夹都符合条件,则需要压缩父文件夹而不是子文件夹。 Dir Structure image

因此,例如,如果我具有如图所示的目录结构,并假设文件夹6下的所有文件均符合条件,但文件夹7下的所有文件均不符合条件,则将满足文件夹7下的条件的文件压缩,但是整个文件夹6都已压缩。如果文件夹6下的所有文件,文件夹7和文件夹3都符合条件,则如果文件夹2下的内容不符合条件,则将压缩文件夹3。如果文件夹2,文件夹3和文件夹1下的内容符合条件,则将文件夹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<>();
    }
}

}