新建 Maven Project,项目结构:
修改 pom.xml 文件,引入依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mk</groupId>
<artifactId>cmd-tree</artifactId>
<version>1.0.0</version>
<description>列出指定目录的结构</description>
<properties>
<commons-lang3.version>3.10</commons-lang3.version>
<logback-classic.version>1.2.3</logback-classic.version>
<lombok.version>1.18.12</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- http://maven.apache.org/plugins/index.html -->
<!-- http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- To create an executable uber JAR, one simply needs to set the main class that serves as the application entry point -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mk.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/cmd-tree/src/main/resources/logback.xml 日志配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 输出到控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<!-- 基于大小以及时间的轮转策略 -->
<!-- 参考:http://www.logback.cn/04%E7%AC%AC%E5%9B%9B%E7%AB%A0Appenders.html -->
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 要写入文件的名称。如果文件不存在,则新建。 -->
<!-- <file>${USER_HOME}/logback.log</file> -->
<file>logback.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>%d{yyyyMMdd}/logback-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>1000KB</maxFileSize>
<!-- 最多保留多少数量的归档文件,将会异步删除旧的文件。 -->
<maxHistory>30</maxHistory>
<!-- 所有归档文件总的大小。当达到这个大小后,旧的归档文件将会被异步的删除。 -->
<totalSizeCap>10MB</totalSizeCap>
</rollingPolicy>
<encoder>
<!-- <pattern>%d{HH:mm:ss.SSS} %-5level [%-10thread] %logger - %msg%n</pattern> -->
<pattern>%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="ROLLING" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
/cmd-tree/src/main/java/com/mk/Application.java 主类
package com.mk;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Application {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String pathname = null;
try {
System.out.format("Please input the location (default is %s): ",
System.getProperty("user.dir"));
pathname = scanner.nextLine();
} catch (Exception e) {
log.error("ERROR! EXCEPTION: {}", e);
scanner.close();
System.exit(0);
}
if (StringUtils.isBlank(pathname)) {
pathname = System.getProperty("user.dir");
}
File root = new File(pathname);
if (!root.exists()) {
log.info("{} does not exist.", pathname);
System.exit(0);
}
Map<String, Integer> counters = listFiles(root, 0, null);
log.info("\nTotal directories: {}", counters.get("directories"));
log.info("Total files: {}", counters.get("files"));
}
/**
*
* @param root 目录
* @param deep 初始值 0
* @param counters 初始值 <code>null</code>
* @return 返回两个计数器。第一个记录文件夹总数,键值 <code>directories</code>;第二个记录文件总数,键值 <code>files</code>
*/
private static Map<String, Integer> listFiles(File root, int deep, Map<String, Integer> counters) {
if (counters == null) {
counters = new HashMap<>();
counters.put("directories", 0);
counters.put("files", 0);
}
deep++;
String indentation = "";
for (int i = 0; i < deep; i++) {
indentation = indentation.concat(" ");
}
indentation = "|".concat(indentation.substring(1));
File[] files = root.listFiles();
List<File> sortedFiles = new ArrayList<>();
List<File> sortedDirectories = new ArrayList<>();
for (File file : files) {
if (file.isDirectory()) {
sortedDirectories.add(file);
} else {
sortedFiles.add(file);
}
}
counters.put("files", counters.get("files") + sortedFiles.size());
indentation = indentation.replace("+", "|").replaceAll("-", " ");
for (File file : sortedFiles) {
log.info("{}{}", indentation, file.getName());
}
counters.put("directories", counters.get("directories") + sortedDirectories.size());
indentation = indentation.replace("|", "+").replaceAll(" ", "-");
for (File file : sortedDirectories) {
log.info("{}{}", indentation, file.getName());
listFiles(file, deep, counters);
}
return counters;
}
}
使用 Maven 打包之后,执行命令 java -jar cmd-tree-1.0.0.jar
,如果不输入目录,则统计当前目录:
G:\Eclipse\eclipse-workspace-spring-boot-20191129\cmd-tree\target>java -jar cmd-tree-1.0.0.jar
Please input the location (default is G:\Eclipse\eclipse-workspace-spring-boot-20191129\cmd-tree\target):
| cmd-tree-1.0.0.jar
| logback.log
| original-cmd-tree-1.0.0.jar
+---classes
| logback.xml
+-------com
+-----------mk
| Application.class
+-------META-INF
| MANIFEST.MF
+-----------maven
+---------------com.mk
+-------------------cmd-tree
| pom.properties
| pom.xml
+---generated-sources
+-------annotations
+---maven-archiver
| pom.properties
+---maven-status
+-------maven-compiler-plugin
+-----------compile
+---------------default-compile
| createdFiles.lst
| inputFiles.lst
+-----------testCompile
+---------------default-testCompile
| inputFiles.lst
+---test-classes
Total directories: 17
Total files: 12