список папок и файлов - PullRequest
0 голосов
/ 19 июня 2020

Я использовал этот код для вывода списка всех папок ...

    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;
}
}

он работает, и это круто, но проблема в том, что он не считает обычные файлы, такие как .txt или .png ... я знаю его написано внутри этого метода, но я не знаю, как исправить это, не разрушая все остальное

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

могу ли я переделать метод или что-то еще ?? (этот код не мой { ссылка })

Ответы [ 4 ]

0 голосов
/ 20 июня 2020

Если ваша иерархия папок очень большая, тогда вызов NIO Files.walkFileTree значительно быстрее при создании имен всех файлов в дереве каталогов по сравнению с многократным вызовом File.list () или File.listFiles () из рекурсивной функции .

Но вам нужно будет изменить logi c вашего кода на различные обратные вызовы FileVisitor, так что это не будет стоить усилий, если только то, что у вас есть, не будет слишком медленным. См .:

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

или

Files.walkFileTree(dir, visitor);
0 голосов
/ 19 июня 2020

попробуйте это

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);
}
0 голосов
/ 19 июня 2020

, вы можете удалить FilenameFilter и использовать только listFiles(). он вернет все файлы и каталоги, содержащиеся в каталоге или null, если вызывается не из каталога File, поэтому перед продолжением важно проверить наличие null. переписать renderFolder() может быть:

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;
}
0 голосов
/ 19 июня 2020

Предполагая, что я понимаю ваш вопрос, это мой ответ:

В вашем заданном коде:

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

вы фильтруете все файлы, найденные в папке, и проверяете, является ли данный файл каталог с .isDirectory (). Таким образом, результирующий массив состоит только из папок.

Если вам нужны папки, а также файлы в результате, вы можете просто удалить фильтр, и у вас будут все файлы / папки в данной папке.

File[] objects = folder.listFiles();

Поскольку теперь код должен также обрабатывать файлы, мы должны немного изменить код, который обрабатывает отступы.

Перед изменением файлов и папок код действовал бы одинаково для каждого элемента в массиве объектов. Но теперь мы должны различать папку и файл.

Таким образом:

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 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;
}

Важное изменение состоит в том, что если объект в массиве не является folder вызывается функция indent, а затем l oop продолжается без вызова renderFolder для текущего файлового объекта.

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

Тестирование в моей тестовой папке привело к следующему:

└──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

, что является точным представлением структуры моей папки.

Это должно решить вашу проблему .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...