0

i used this code for list all folders...

    public static void main(String[] args) throws Exception {
    File root = new File("C:\\Users\\resti\\Desktop\\example");
    if (!root.isDirectory())
    {
        System.out.println("some_text");
    }

    int level = 0;
        System.out.println(renderFolder(root, level, new StringBuilder(), false, new ArrayList<>()));

        }
    private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast, List<Boolean> hierarchyTree) {
    indent(sb, level, isLast, hierarchyTree).append(folder.getName()).append("\n");

    File[] objects = folder.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File current, String name) {
            return new File(current, name).isDirectory();
        }
    });

    for (int i = 0; i < objects.length; i++) {
        boolean last = ((i + 1) == objects.length);

        // this means if the current folder will still need to print subfolders at this level, if yes, then we need to continue print |
        hierarchyTree.add(i != objects.length - 1);
        renderFolder(objects[i], level + 1, sb, last, hierarchyTree);

        // pop the last value as we return from a lower level to a higher level
        hierarchyTree.remove(hierarchyTree.size() - 1);
    }
    return sb;
}


private static StringBuilder indent(StringBuilder sb, int level, boolean isLast, List<Boolean> hierarchyTree) {
    String indentContent = "\u2502   ";
    for (int i = 0; i < hierarchyTree.size() - 1; ++i) {
        // determines if we need to print | at this level to show the tree structure
        // i.e. if this folder has a sibling foler that is going to be printed later
        if (hierarchyTree.get(i)) {
            sb.append(indentContent);
        } else {
            sb.append("    "); // otherwise print empty space
        }
    }

    if (level > 0) {
        sb.append(isLast
                ? "\u2514\u2500\u2500"
                : "\u251c\u2500\u2500");
    }

    return sb;
}
}

it works and its cool but the problem is that it doesnt count normal Files like .txt or .png... i know its writen inside this method but idk how to fix it without destroing everything else

File[] objects = folder.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File current, String name) {
            return new File(current, name).isDirectory();
        }
    });

can i remake the method or somethink else ?? (this code is not mine https://stackoverflow.com/a/33438475/13547682 )

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43

4 Answers4

0

Assuming that I understand your question this is my answer:

In your given code:

File[] objects = folder.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File current, String name) {
            return new File(current, name).isDirectory();
        }
);

you are filtering all files found in the folder and check if a given file is a directory with .isDirectory(). Thus the resulting array only consists of folders.

If you want folders as well as files as a result, you can just remove the filter and you have all files/folders in the given folder.

File[] objects = folder.listFiles();

Because the code now has to also handle files, we have to change a little bit of the code that handles the indentation.

Before the change to files and folders, the code would act the same way for each element in the objects array. But now we to make a distinction between folder and file.

Thus:

private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast, List<Boolean> hierarchyTree) {
    indent(sb, level, isLast, hierarchyTree).append(folder.getName()).append("\n");

    File[] objects = folder.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File current, String name) {
            return new File(current, name).isDirectory();
        }
    });

    for (int i = 0; i < objects.length; i++) {
        boolean last = ((i + 1) == objects.length);

        // this means if the current folder will still need to print subfolders at this level, if yes, then we need to continue print |
        hierarchyTree.add(i != objects.length - 1);
        renderFolder(objects[i], level + 1, sb, last, hierarchyTree);

        // pop the last value as we return from a lower level to a higher level
        hierarchyTree.remove(hierarchyTree.size() - 1);
    }
    return sb;
}

Would have to be altered to look something like:

private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast, List<Boolean> hierarchyTree) {
        indent(sb, level, isLast, hierarchyTree).append(folder.getName()).append("\n");

        File[] objects = folder.listFiles();

        for (int i = 0; i < objects.length; i++) {
            boolean last = ((i + 1) == objects.length);
            hierarchyTree.add(i != objects.length - 1);
            if (objects[i].isDirectory() == false) {
                indent(sb, level, isLast, hierarchyTree).append(objects[i].getName()).append("\n");
                hierarchyTree.remove(hierarchyTree.size() - 1);
                continue;
            }
            // this means if the current folder will still need to print subfolders at this level, if yes, then we need to continue print |
            renderFolder(objects[i], level + 1, sb, last, hierarchyTree);

            // pop the last value as we return from a lower level to a higher level
            hierarchyTree.remove(hierarchyTree.size() - 1);
        }
        return sb;
}

The important change is that if an object in the array is not a folder, the indent function is called and then the loop is continued without calling renderFolder on the current file object.

if (objects[i].isDirectory() == false) {
        indent(sb, level, isLast, hierarchyTree).append(objects[i].getName()).append("\n");
        hierarchyTree.remove(hierarchyTree.size() - 1);
        continue;
}

Testing it on my test folder it resulted in this:

└──62476474
    ├──target
    │   ├──generated-sources
    │   │   └──annotations
    │   ├──classes
    │   │   ├──Main.class
    │   └──maven-status
    │       └──maven-compiler-plugin
    │           └──compile
    │               └──default-compile
    │                   └──inputFiles.lst
    │                   └──createdFiles.lst
    └──pom.xml
    └──src
        ├──test
        │   └──java
        └──main
            └──java
                └──Main.java

which is an accurate representation of my folder structure.

This should solve your problem.

Liberatys
  • 223
  • 2
  • 12
0

you can remove the FilenameFilter and use just listFiles(). it will return all files and directories contained in the directory or null if called on a non-directory File so it's important to check for null before proceeding. a rewrite of renderFolder() could be:

private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast, List<Boolean> hierarchyTree) {
        indent(sb, level, isLast, hierarchyTree).append(folder.getName()).append("\n");

        File[] objects = folder.listFiles();

        if (objects == null)
                // not a directory, there is nothing to iterate over, return immediately 
                return sb;

        for (int i = 0; i < objects.length; i++) {
                boolean last = ((i + 1) == objects.length);

                // this means if the current folder will still need to print subfolders at this level, if yes, then we need to continue print |
                hierarchyTree.add(i != objects.length - 1);
                renderFolder(objects[i], level + 1, sb, last, hierarchyTree);

                // pop the last value as we return from a lower level to a higher level
                hierarchyTree.remove(hierarchyTree.size() - 1);
        }
        return sb;
}
MarcoLucidi
  • 2,007
  • 1
  • 5
  • 8
0

If your folder hierarchy is very large then the NIO Files.walkFileTree call is significantly faster at producing the names of all files in a directory tree compared to repeatedly calling File.list() or File.listFiles() from a recursive function.

But you'd need to alter logic of your code into the various callbacks of a FileVisitor so it will not be worth the effort unless what you have is too slow. See:

Files.walkFileTree(dir, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor);

or

Files.walkFileTree(dir, visitor);
DuncG
  • 12,137
  • 2
  • 21
  • 33
-1

try this

try {
    String[] command = { "/bin/sh", "-c", "cd /var; ls -l" };
    System.out.println("shell script command:");
    Stream.of(command).forEach(e -> System.out.println(e));
    Process process = Runtime.getRuntime().exec(command);
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));

    String line = null;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (Exception e) {
    System.out.println("Error while executing: " + e);
}
kumar gabs
  • 29
  • 4
  • `"/bin/sh", "-c", "cd /var; ls -l"` will never work on Windows and I think invoking an external program like this is really a wrong approach here – MarcoLucidi Jun 19 '20 at 19:58