伊成博客
伊成博客

如何使用Java打印项目目录结构

“如何使用Java打印项目目录结构”

背景

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

可配置项

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

效果图

“如何使用Java打印项目目录结构”

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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));
}
}

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

支付宝打赏 微信打赏

如果本文对你有所帮助,请打赏 1元就足够感动我 :)