8

如何使用Java代码打印项目目录结构,源码在里面剩下的给大家发挥

 3 years ago
source link: https://zhuanlan.zhihu.com/p/103040661
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

如何使用Java代码打印项目目录结构,源码在里面剩下的给大家发挥

热衷于收集和创造优质技术文章

背景

看见很多代码在GITHUB上都有项目的目录结构,想要介绍一个项目各个包的内容,但又不想手敲目录结构,于是写了个工具类生成目录结构。

可配置项

1.忽略文件夹:可以忽略一个或多个文件夹;
2.文件夹折叠开关:连续的空文件夹会被默认打印成包名,但可以通过开关打开和关闭;
3.是否生成文件:考虑到多数情况只需要生成目录不需要生成具体文件,所以有这个开关,控制是否打印文件。

效果图

v2-e73d421e2f5a0e7229965e143c9eae8f_720w.jpg

源码

package com.lvoyee.esblog.utils;

import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
 * @author: luo_yun
 * @date: 2019/3/13 19:57
 * @description:
 */
public class PackageGenerator {
    private final static String[] TABS = new String[]{"└── ", "├── ", "│   ", "    "};

    public static String generate(String rootDir) throws Exception {
        return generate(rootDir, new HashSet<>(), true, false);
    }

    public static String generate(String rootDir, Boolean packageCollapse) throws Exception {
        return generate(rootDir, new HashSet<>(), packageCollapse, false);
    }

    public static String generate(String rootDir, Set<String> ignoreDirs) throws Exception {
        return generate(rootDir, ignoreDirs, true, false);
    }

    /**
     * all directories and files of a specific path
     *
     * @param rootDir         root dir
     * @param ignoreDirs      a set of dir to ignore.
     *                        if parent ignored, all children will be ignored too
     * @param packageCollapse if true, empty packages will fold to java package name.
     *                        like IntelliJ IDEA project outline(default, not flatten packages mode)
     *                        default true
     * @param generateFile    if true, file will be generated, otherwise only directory will be generated
     *                        default false
     * @return formatted outline string
     * @throws Exception
     */
    public static String generate(String rootDir, Set<String> ignoreDirs, Boolean packageCollapse, Boolean generateFile) throws Exception {
        if (StringUtils.isBlank(rootDir)) {
            throw new NullPointerException("null root dir!");
        }
        File file = new File(rootDir);
        if (!file.exists()) {
            throw new FileNotFoundException("root dir not exists!");
        }

        if (!file.isDirectory()) {
            throw new IllegalArgumentException("root dir is not a directory!");
        }

        StringBuilder stringBuilder = new StringBuilder(file.getName());

        generateChildren(file, stringBuilder, "", ignoreDirs, packageCollapse, generateFile);

        return stringBuilder.toString();
    }

    /**
     * generate directory structure with recursive function
     *
     * @param file            dir to generate
     * @param stringBuilder   outer string builder for
     * @param level           depth of file or directory which determines how many blanks to display before this file or directory
     * @param ignoreDirs      a set of dir to ignore
     * @param packageCollapse if true, empty packages will fold to java package name
     */
    private static void generateChildren(File file, StringBuilder stringBuilder, String level, Set<String> ignoreDirs, Boolean packageCollapse, Boolean generateFile) {
        File[] childes = file.listFiles();
        if (childes == null) {
            return;
        }
        int lastDirIndex = lastDirIndex(childes, ignoreDirs, generateFile);
        int dirCnt = dirCnt(childes, ignoreDirs, generateFile);

        if (lastDirIndex >= 0) {
            if (dirCnt == 1) {
                if (packageCollapse && childes[lastDirIndex].isDirectory()) {
                    stringBuilder.append(".").append(childes[lastDirIndex].getName());
                    generateChildren(childes[lastDirIndex], stringBuilder, level, ignoreDirs, packageCollapse, generateFile);
                    return;
                } else {
                    stringBuilder.append("\n").append(level).append(TABS[0]).append(childes[lastDirIndex].getName());
                    generateChildren(childes[lastDirIndex], stringBuilder, level + TABS[3], ignoreDirs, packageCollapse, generateFile);
                    return;
                }
            }

            for (int i = 0; i < childes.length; i++) {
                if ((childes[i].isDirectory() && !ignoreDirs.contains(childes[i].getName())) || generateFile) {
                    stringBuilder.append("\n").append(level);
                    if (i == lastDirIndex) {
                        stringBuilder.append(TABS[0]).append(childes[i].getName());
                        generateChildren(childes[i], stringBuilder, level + (TABS[3]), ignoreDirs, packageCollapse, generateFile);
                    } else {
                        stringBuilder.append(TABS[1]).append(childes[i].getName());
                        generateChildren(childes[i], stringBuilder, level + (TABS[2]), ignoreDirs, packageCollapse, generateFile);
                    }
                }
            }
        }
    }

    private static int dirCnt(File[] childes, Set<String> ignoreDirs, Boolean generateFile) {
        int cnt = 0;

        if (childes == null || childes.length == 0) {
            return cnt;
        }

        for (int i = 0; i < childes.length; i++) {
            if ((childes[i].isDirectory() && !ignoreDirs.contains(childes[i].getName())) || generateFile) {
                cnt++;
            }
        }

        return cnt;
    }

    private static int lastDirIndex(File[] childes, Set<String> ignoreDirs, Boolean generateFile) {
        int index = -1;

        if (childes == null || childes.length == 0) {
            return index;
        }
        for (int i = 0; i < childes.length; i++) {
            if ((childes[i].isDirectory() && !ignoreDirs.contains(childes[i].getName())) || generateFile) {
                index = i;
            }
        }

        return index;
    }

    public static void main(String args[]) throws Exception {
        System.out.print(generate(System.getProperty("user.dir") + "/src/main/java", new HashSet<>(Arrays.asList(".idea", "target", ".git")), true, true));
        System.out.println("\n\n------------------------------------------------\n");
        System.out.print(generate(System.getProperty("user.dir") + "/src/main/java", new HashSet<>(Arrays.asList(".idea", "target", ".git")), false, false));
    }
}

有需要的可以直接赋值以上代码,放在自己项目里面充当一个工具类即可!

感谢大家的阅读,需要获取电子书籍的朋友私信我即可

v2-3537d8de15d76a070e7c72805a3cc62b_720w.jpgv2-44fc310f6085134d62b40d3060c22774_720w.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK