init/push
This commit is contained in:
43
.gitignore
vendored
Normal file
43
.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
.kotlin
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
/target
|
||||||
|
/.idea
|
||||||
|
/.mvn
|
||||||
73
LICENSE
Normal file
73
LICENSE
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2026 database-mysql
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
123
README.md
Normal file
123
README.md
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# GNU Java Utils Library
|
||||||
|
|
||||||
|
一个轻量级 Java 工具库,提供常用的压缩/解压与终端彩色输出功能。
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- **Java 25**
|
||||||
|
- **Maven** 构建
|
||||||
|
- **Apache Commons Compress 1.28.0**(压缩功能依赖)
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
src/main/java/top/gtb520/java/gnu/java/utils/library/
|
||||||
|
├── main.java # 统一入口接口
|
||||||
|
├── utils/
|
||||||
|
│ ├── compress/
|
||||||
|
│ │ └── compress.java # 压缩/解压工具类
|
||||||
|
│ └── print/
|
||||||
|
│ ├── echo.java # 终端彩色输出工具类
|
||||||
|
│ └── ColorNameEnum.java # 颜色名称枚举
|
||||||
|
```
|
||||||
|
|
||||||
|
## 功能模块
|
||||||
|
|
||||||
|
### 1. 压缩/解压 (`compress`)
|
||||||
|
|
||||||
|
支持 **Tar.Gz** 和 **Zip** 两种压缩格式的压缩与解压操作,支持单文件和整个目录的递归处理。
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|------|------|------|
|
||||||
|
| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
|
||||||
|
| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
||||||
|
| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
|
||||||
|
| `compress.UnZip(source, dest)` | 解压 `.zip` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
||||||
|
|
||||||
|
**使用示例:**
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.compress.compress;
|
||||||
|
|
||||||
|
// 压缩目录为 Tar.Gz
|
||||||
|
compress.MakeTarGz("/path/to/source", "/path/to/output.tar.gz");
|
||||||
|
|
||||||
|
// 解压 Tar.Gz
|
||||||
|
compress.UnTarGz("/path/to/output.tar.gz", "/path/to/dest");
|
||||||
|
|
||||||
|
// 压缩文件为 Zip
|
||||||
|
compress.MakeZip("/path/to/file.txt", "/path/to/output.zip");
|
||||||
|
|
||||||
|
// 解压 Zip
|
||||||
|
compress.UnZip("/path/to/output.zip", "/path/to/dest");
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以通过统一入口 `main` 接口调用:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
|
||||||
|
main.compress.UnTarGz(source, dest);
|
||||||
|
main.compress.TarGz(source, dest);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 终端彩色输出 (`echo`)
|
||||||
|
|
||||||
|
基于 ANSI 转义序列,在终端中输出彩色文本。
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|------|------|------|
|
||||||
|
| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本内容,`color` 颜色枚举 |
|
||||||
|
| `echo.ColorHexPrintln(message, hexColor)` | 使用自定义 ANSI 颜色码打印 | `message` 文本内容,`hexColor` ANSI 颜色代码 |
|
||||||
|
|
||||||
|
**支持的颜色枚举 (`ColorNameEnum`):**
|
||||||
|
|
||||||
|
| 枚举值 | 颜色 |
|
||||||
|
|--------|------|
|
||||||
|
| `RED` | 红色 |
|
||||||
|
| `GREEN` | 绿色 |
|
||||||
|
| `YELLOW` | 黄色 |
|
||||||
|
| `BLUE` | 蓝色 |
|
||||||
|
| `PURPLE` | 紫色 |
|
||||||
|
| `CYAN` | 青色 |
|
||||||
|
|
||||||
|
**使用示例:**
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
||||||
|
|
||||||
|
// 使用预定义颜色
|
||||||
|
echo.ColorPrintln("错误信息", ColorNameEnum.RED);
|
||||||
|
echo.ColorPrintln("成功信息", ColorNameEnum.GREEN);
|
||||||
|
|
||||||
|
// 使用自定义 ANSI 颜色码
|
||||||
|
echo.ColorHexPrintln("自定义橙色", "38;5;208");
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以通过统一入口 `main` 接口调用:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
||||||
|
|
||||||
|
main.echo.Println("警告信息", ColorNameEnum.YELLOW);
|
||||||
|
main.echo.ColorHexPrintln("自定义颜色", "31");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn compile
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异常处理
|
||||||
|
|
||||||
|
压缩/解压方法在以下情况会抛出 `IllegalArgumentException`:
|
||||||
|
|
||||||
|
- **压缩时**:源路径不存在
|
||||||
|
- **解压时**:目标路径不是有效的目录
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
本项目仅供学习与个人使用。
|
||||||
1
cp.txt
Normal file
1
cp.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
C:\Users\Administrator\.m2\repository\org\apache\commons\commons-compress\1.28.0\commons-compress-1.28.0.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.19.0\commons-codec-1.19.0.jar;C:\Users\Administrator\.m2\repository\commons-io\commons-io\2.20.0\commons-io-2.20.0.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.18.0\commons-lang3-3.18.0.jar
|
||||||
25
pom.xml
Normal file
25
pom.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>top.gtb520.java.gnu</groupId>
|
||||||
|
<artifactId>gnu_java_utils_library</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>25</maven.compiler.source>
|
||||||
|
<maven.compiler.target>25</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
<version>1.28.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library;
|
||||||
|
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
||||||
|
|
||||||
|
public interface main {
|
||||||
|
// 压缩包操作相关接口与方法
|
||||||
|
interface compress {
|
||||||
|
// 解压Tar.Gz压缩包
|
||||||
|
static void UnTarGz(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
top.gtb520.java.gnu.java.utils.library.utils.compress.compress.UnTarGz(sourceFilePanth, destFilePanth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 压缩文件或目录为Tar.Gz压缩包
|
||||||
|
static void TarGz(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
top.gtb520.java.gnu.java.utils.library.utils.compress.compress.MakeTarGz(sourceFilePanth, destFilePanth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终端打印接口与方法
|
||||||
|
interface echo {
|
||||||
|
// 使用预定义的颜色名称在终端打印彩色文本
|
||||||
|
static void Println(String Message, ColorNameEnum ColorName) {
|
||||||
|
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorPrintln(Message, ColorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用自定义十六进制颜色码在终端打印彩色文本
|
||||||
|
static void ColorHexPrintln(String Message, String ColorCode) {
|
||||||
|
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorHexPrintln(Message, ColorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.compress;
|
||||||
|
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||||
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||||
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩包
|
||||||
|
*/
|
||||||
|
public class compress {
|
||||||
|
/**
|
||||||
|
* 解压Tar.Gz压缩包
|
||||||
|
*
|
||||||
|
* @param sourceFilePanth 压缩包路径
|
||||||
|
* @param destFilePanth 解压路径
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void UnTarGz(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
Path destPath = Paths.get(destFilePanth);
|
||||||
|
if (!Files.isDirectory(destPath)) {
|
||||||
|
throw new IllegalArgumentException("目标路径必须是有效的目录");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream fileIn = Files.newInputStream(Paths.get(sourceFilePanth));
|
||||||
|
BufferedInputStream bufferedIn = new BufferedInputStream(fileIn);
|
||||||
|
GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(bufferedIn);
|
||||||
|
TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)) {
|
||||||
|
|
||||||
|
TarArchiveEntry entry;
|
||||||
|
while ((entry = tarIn.getNextTarEntry()) != null) {
|
||||||
|
Path targetPath = destPath.resolve(entry.getName());
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
Files.createDirectories(targetPath);
|
||||||
|
} else {
|
||||||
|
Files.createDirectories(targetPath.getParent());
|
||||||
|
Files.copy(tarIn, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩Tar.Gz压缩包
|
||||||
|
*
|
||||||
|
* @param sourceFilePanth 源文件或目录路径
|
||||||
|
* @param destFilePanth 压缩包路径
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void MakeTarGz(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
Path sourcePath = Paths.get(sourceFilePanth);
|
||||||
|
if (!Files.exists(sourcePath)) {
|
||||||
|
throw new IllegalArgumentException("源路径不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (OutputStream fileOut = Files.newOutputStream(Paths.get(destFilePanth));
|
||||||
|
BufferedOutputStream bufferedOut = new BufferedOutputStream(fileOut);
|
||||||
|
GzipCompressorOutputStream gzipOut = new GzipCompressorOutputStream(bufferedOut);
|
||||||
|
TarArchiveOutputStream tarOut = new TarArchiveOutputStream(gzipOut)) {
|
||||||
|
|
||||||
|
tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
|
||||||
|
|
||||||
|
if (Files.isDirectory(sourcePath)) {
|
||||||
|
Files.walkFileTree(sourcePath, new java.nio.file.SimpleFileVisitor<Path>() {
|
||||||
|
@Override
|
||||||
|
public java.nio.file.FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws java.io.IOException {
|
||||||
|
String entryName = sourcePath.relativize(file).toString().replace('\\', '/');
|
||||||
|
TarArchiveEntry entry = new TarArchiveEntry(file.toFile(), entryName);
|
||||||
|
tarOut.putArchiveEntry(entry);
|
||||||
|
Files.copy(file, tarOut);
|
||||||
|
tarOut.closeArchiveEntry();
|
||||||
|
return java.nio.file.FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.nio.file.FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws java.io.IOException {
|
||||||
|
if (!dir.equals(sourcePath)) {
|
||||||
|
String entryName = sourcePath.relativize(dir).toString().replace('\\', '/') + "/";
|
||||||
|
TarArchiveEntry entry = new TarArchiveEntry(entryName);
|
||||||
|
tarOut.putArchiveEntry(entry);
|
||||||
|
tarOut.closeArchiveEntry();
|
||||||
|
}
|
||||||
|
return java.nio.file.FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
TarArchiveEntry entry = new TarArchiveEntry(sourcePath.toFile(), sourcePath.getFileName().toString());
|
||||||
|
tarOut.putArchiveEntry(entry);
|
||||||
|
Files.copy(sourcePath, tarOut);
|
||||||
|
tarOut.closeArchiveEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩.zip压缩包
|
||||||
|
*
|
||||||
|
* @param sourceFilePanth 源文件或目录路径
|
||||||
|
* @param destFilePanth 压缩包路径
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void MakeZip(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
Path sourcePath = Paths.get(sourceFilePanth);
|
||||||
|
if (!Files.exists(sourcePath)) {
|
||||||
|
throw new IllegalArgumentException("源路径不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (OutputStream fileOut = Files.newOutputStream(Paths.get(destFilePanth));
|
||||||
|
BufferedOutputStream bufferedOut = new BufferedOutputStream(fileOut);
|
||||||
|
ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bufferedOut)) {
|
||||||
|
|
||||||
|
if (Files.isDirectory(sourcePath)) {
|
||||||
|
Files.walkFileTree(sourcePath, new java.nio.file.SimpleFileVisitor<Path>() {
|
||||||
|
@Override
|
||||||
|
public java.nio.file.FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws java.io.IOException {
|
||||||
|
String entryName = sourcePath.relativize(file).toString().replace('\\', '/');
|
||||||
|
ZipArchiveEntry entry = new ZipArchiveEntry(entryName);
|
||||||
|
zipOut.putArchiveEntry(entry);
|
||||||
|
Files.copy(file, zipOut);
|
||||||
|
zipOut.closeArchiveEntry();
|
||||||
|
return java.nio.file.FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.nio.file.FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws java.io.IOException {
|
||||||
|
if (!dir.equals(sourcePath)) {
|
||||||
|
String entryName = sourcePath.relativize(dir).toString().replace('\\', '/') + "/";
|
||||||
|
ZipArchiveEntry entry = new ZipArchiveEntry(entryName);
|
||||||
|
zipOut.putArchiveEntry(entry);
|
||||||
|
zipOut.closeArchiveEntry();
|
||||||
|
}
|
||||||
|
return java.nio.file.FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ZipArchiveEntry entry = new ZipArchiveEntry(sourcePath.getFileName().toString());
|
||||||
|
zipOut.putArchiveEntry(entry);
|
||||||
|
Files.copy(sourcePath, zipOut);
|
||||||
|
zipOut.closeArchiveEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压.zip压缩包
|
||||||
|
*
|
||||||
|
* @param sourceFilePanth 压缩包路径
|
||||||
|
* @param destFilePanth 解压路径
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void UnZip(String sourceFilePanth, String destFilePanth) throws Exception {
|
||||||
|
Path destPath = Paths.get(destFilePanth);
|
||||||
|
if (!Files.isDirectory(destPath)) {
|
||||||
|
throw new IllegalArgumentException("目标路径必须是有效的目录");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream fileIn = Files.newInputStream(Paths.get(sourceFilePanth));
|
||||||
|
BufferedInputStream bufferedIn = new BufferedInputStream(fileIn);
|
||||||
|
ZipArchiveInputStream zipIn = new ZipArchiveInputStream(bufferedIn)) {
|
||||||
|
|
||||||
|
ZipArchiveEntry entry;
|
||||||
|
while ((entry = zipIn.getNextEntry()) != null) {
|
||||||
|
Path targetPath = destPath.resolve(entry.getName());
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
Files.createDirectories(targetPath);
|
||||||
|
} else {
|
||||||
|
Files.createDirectories(targetPath.getParent());
|
||||||
|
Files.copy(zipIn, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.print;
|
||||||
|
|
||||||
|
public enum ColorNameEnum {
|
||||||
|
RED, GREEN, YELLOW, BLUE, PURPLE, CYAN;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.print;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终端彩色输出工具类
|
||||||
|
* 提供基于 ANSI 转义序列的终端彩色打印功能
|
||||||
|
*/
|
||||||
|
public class echo {
|
||||||
|
// 终端彩色打印
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用自定义十六进制颜色码在终端打印彩色文本
|
||||||
|
*
|
||||||
|
* @param Message 要打印的文本内容
|
||||||
|
* @param HexColor ANSI 颜色代码(如 "31" 表示红色,"38;5;208" 表示扩展色)
|
||||||
|
*/
|
||||||
|
public static void ColorHexPrintln(String Message, String HexColor) {
|
||||||
|
System.out.println("\033[" + HexColor + "m" + Message + "\033[0m");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用预定义的颜色名称在终端打印彩色文本
|
||||||
|
*
|
||||||
|
* @param Message 要打印的文本内容
|
||||||
|
* @param ColorName 颜色名称,支持:RED、GREEN、YELLOW、BLUE、PURPLE、CYAN;传入不支持的名称则按默认颜色输出
|
||||||
|
*/
|
||||||
|
public static void ColorPrintln(String Message, ColorNameEnum ColorName) {
|
||||||
|
// 根据颜色名称映射对应的 ANSI 颜色转义序列
|
||||||
|
switch (ColorName) {
|
||||||
|
case RED:
|
||||||
|
System.out.println("\033[31m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
case GREEN:
|
||||||
|
System.out.println("\033[32m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
case YELLOW:
|
||||||
|
System.out.println("\033[33m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
case BLUE:
|
||||||
|
System.out.println("\033[34m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
case PURPLE:
|
||||||
|
System.out.println("\033[35m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
case CYAN:
|
||||||
|
System.out.println("\033[36m" + Message + "\033[0m");
|
||||||
|
break;
|
||||||
|
// 未匹配到已知颜色名称时,以默认颜色输出
|
||||||
|
default:
|
||||||
|
System.out.println(Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
281
src/test/java/compressTest.java
Normal file
281
src/test/java/compressTest.java
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.compress.compress;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class compressTest {
|
||||||
|
|
||||||
|
static int passed = 0;
|
||||||
|
static int failed = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("========== compress 测试开始 ==========");
|
||||||
|
|
||||||
|
testMakeZipAndUnZipSingleFile();
|
||||||
|
testMakeZipAndUnZipDirectory();
|
||||||
|
testMakeTarGzAndUnTarGzSingleFile();
|
||||||
|
testMakeTarGzAndUnTarGzDirectory();
|
||||||
|
testMakeZipSourceNotExist();
|
||||||
|
testUnZipDestNotDirectory();
|
||||||
|
testMakeTarGzSourceNotExist();
|
||||||
|
testUnTarGzDestNotDirectory();
|
||||||
|
|
||||||
|
System.out.println("========================================");
|
||||||
|
System.out.println("测试完成: 通过 " + passed + ", 失败 " + failed);
|
||||||
|
if (failed > 0) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试单文件的 Zip 压缩与解压
|
||||||
|
*/
|
||||||
|
static void testMakeZipAndUnZipSingleFile() throws Exception {
|
||||||
|
String testName = "testMakeZipAndUnZipSingleFile";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
// 准备源文件
|
||||||
|
Path sourceFile = tempDir.resolve("source.txt");
|
||||||
|
Files.writeString(sourceFile, "Hello, Zip!");
|
||||||
|
|
||||||
|
// 压缩
|
||||||
|
Path zipFile = tempDir.resolve("output.zip");
|
||||||
|
compress.MakeZip(sourceFile.toString(), zipFile.toString());
|
||||||
|
assertCondition(testName + " - 压缩文件应存在", Files.exists(zipFile));
|
||||||
|
|
||||||
|
// 解压
|
||||||
|
Path unzipDir = tempDir.resolve("unzip");
|
||||||
|
Files.createDirectories(unzipDir);
|
||||||
|
compress.UnZip(zipFile.toString(), unzipDir.toString());
|
||||||
|
|
||||||
|
Path resultFile = unzipDir.resolve("source.txt");
|
||||||
|
assertCondition(testName + " - 解压文件应存在", Files.exists(resultFile));
|
||||||
|
assertCondition(testName + " - 内容应一致",
|
||||||
|
"Hello, Zip!".equals(Files.readString(resultFile)));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试目录的 Zip 压缩与解压
|
||||||
|
*/
|
||||||
|
static void testMakeZipAndUnZipDirectory() throws Exception {
|
||||||
|
String testName = "testMakeZipAndUnZipDirectory";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
// 准备源目录结构
|
||||||
|
Path sourceDir = tempDir.resolve("source");
|
||||||
|
Files.createDirectories(sourceDir.resolve("sub"));
|
||||||
|
Files.writeString(sourceDir.resolve("a.txt"), "file a");
|
||||||
|
Files.writeString(sourceDir.resolve("sub/b.txt"), "file b");
|
||||||
|
|
||||||
|
// 压缩
|
||||||
|
Path zipFile = tempDir.resolve("dir_output.zip");
|
||||||
|
compress.MakeZip(sourceDir.toString(), zipFile.toString());
|
||||||
|
assertCondition(testName + " - 压缩文件应存在", Files.exists(zipFile));
|
||||||
|
|
||||||
|
// 解压
|
||||||
|
Path unzipDir = tempDir.resolve("unzip_dir");
|
||||||
|
Files.createDirectories(unzipDir);
|
||||||
|
compress.UnZip(zipFile.toString(), unzipDir.toString());
|
||||||
|
|
||||||
|
assertCondition(testName + " - 文件a应存在",
|
||||||
|
Files.exists(unzipDir.resolve("a.txt")));
|
||||||
|
assertCondition(testName + " - 文件b应存在",
|
||||||
|
Files.exists(unzipDir.resolve("sub/b.txt")));
|
||||||
|
assertCondition(testName + " - 文件a内容应一致",
|
||||||
|
"file a".equals(Files.readString(unzipDir.resolve("a.txt"))));
|
||||||
|
assertCondition(testName + " - 文件b内容应一致",
|
||||||
|
"file b".equals(Files.readString(unzipDir.resolve("sub/b.txt"))));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试单文件的 Tar.Gz 压缩与解压
|
||||||
|
*/
|
||||||
|
static void testMakeTarGzAndUnTarGzSingleFile() throws Exception {
|
||||||
|
String testName = "testMakeTarGzAndUnTarGzSingleFile";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
// 准备源文件
|
||||||
|
Path sourceFile = tempDir.resolve("source.txt");
|
||||||
|
Files.writeString(sourceFile, "Hello, TarGz!");
|
||||||
|
|
||||||
|
// 压缩
|
||||||
|
Path tarGzFile = tempDir.resolve("output.tar.gz");
|
||||||
|
compress.MakeTarGz(sourceFile.toString(), tarGzFile.toString());
|
||||||
|
assertCondition(testName + " - 压缩文件应存在", Files.exists(tarGzFile));
|
||||||
|
|
||||||
|
// 解压
|
||||||
|
Path untarDir = tempDir.resolve("untar");
|
||||||
|
Files.createDirectories(untarDir);
|
||||||
|
compress.UnTarGz(tarGzFile.toString(), untarDir.toString());
|
||||||
|
|
||||||
|
Path resultFile = untarDir.resolve("source.txt");
|
||||||
|
assertCondition(testName + " - 解压文件应存在", Files.exists(resultFile));
|
||||||
|
assertCondition(testName + " - 内容应一致",
|
||||||
|
"Hello, TarGz!".equals(Files.readString(resultFile)));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试目录的 Tar.Gz 压缩与解压
|
||||||
|
*/
|
||||||
|
static void testMakeTarGzAndUnTarGzDirectory() throws Exception {
|
||||||
|
String testName = "testMakeTarGzAndUnTarGzDirectory";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
// 准备源目录结构
|
||||||
|
Path sourceDir = tempDir.resolve("source");
|
||||||
|
Files.createDirectories(sourceDir.resolve("sub"));
|
||||||
|
Files.writeString(sourceDir.resolve("a.txt"), "file a");
|
||||||
|
Files.writeString(sourceDir.resolve("sub/b.txt"), "file b");
|
||||||
|
|
||||||
|
// 压缩
|
||||||
|
Path tarGzFile = tempDir.resolve("dir_output.tar.gz");
|
||||||
|
compress.MakeTarGz(sourceDir.toString(), tarGzFile.toString());
|
||||||
|
assertCondition(testName + " - 压缩文件应存在", Files.exists(tarGzFile));
|
||||||
|
|
||||||
|
// 解压
|
||||||
|
Path untarDir = tempDir.resolve("untar_dir");
|
||||||
|
Files.createDirectories(untarDir);
|
||||||
|
compress.UnTarGz(tarGzFile.toString(), untarDir.toString());
|
||||||
|
|
||||||
|
assertCondition(testName + " - 文件a应存在",
|
||||||
|
Files.exists(untarDir.resolve("a.txt")));
|
||||||
|
assertCondition(testName + " - 文件b应存在",
|
||||||
|
Files.exists(untarDir.resolve("sub/b.txt")));
|
||||||
|
assertCondition(testName + " - 文件a内容应一致",
|
||||||
|
"file a".equals(Files.readString(untarDir.resolve("a.txt"))));
|
||||||
|
assertCondition(testName + " - 文件b内容应一致",
|
||||||
|
"file b".equals(Files.readString(untarDir.resolve("sub/b.txt"))));
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试压缩不存在的源路径应抛出异常
|
||||||
|
*/
|
||||||
|
static void testMakeZipSourceNotExist() {
|
||||||
|
String testName = "testMakeZipSourceNotExist";
|
||||||
|
try {
|
||||||
|
compress.MakeZip("not_exist_path", "output.zip");
|
||||||
|
assertCondition(testName + " - 应抛出异常", false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertCondition(testName + " - 应抛出IllegalArgumentException", true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertCondition(testName + " - 异常类型不正确: " + e.getClass().getName(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试解压到非目录路径应抛出异常
|
||||||
|
*/
|
||||||
|
static void testUnZipDestNotDirectory() throws Exception {
|
||||||
|
String testName = "testUnZipDestNotDirectory";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
// 创建一个文件作为解压目标(非目录)
|
||||||
|
Path notDir = tempDir.resolve("not_a_dir.txt");
|
||||||
|
Files.writeString(notDir, "I am a file");
|
||||||
|
|
||||||
|
// 先创建一个合法zip
|
||||||
|
Path sourceFile = tempDir.resolve("src.txt");
|
||||||
|
Files.writeString(sourceFile, "test");
|
||||||
|
Path zipFile = tempDir.resolve("test.zip");
|
||||||
|
compress.MakeZip(sourceFile.toString(), zipFile.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
compress.UnZip(zipFile.toString(), notDir.toString());
|
||||||
|
assertCondition(testName + " - 应抛出异常", false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertCondition(testName + " - 应抛出IllegalArgumentException", true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertCondition(testName + " - 异常类型不正确: " + e.getClass().getName(), false);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试TarGz压缩不存在的源路径应抛出异常
|
||||||
|
*/
|
||||||
|
static void testMakeTarGzSourceNotExist() {
|
||||||
|
String testName = "testMakeTarGzSourceNotExist";
|
||||||
|
try {
|
||||||
|
compress.MakeTarGz("not_exist_path", "output.tar.gz");
|
||||||
|
assertCondition(testName + " - 应抛出异常", false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertCondition(testName + " - 应抛出IllegalArgumentException", true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertCondition(testName + " - 异常类型不正确: " + e.getClass().getName(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试TarGz解压到非目录路径应抛出异常
|
||||||
|
*/
|
||||||
|
static void testUnTarGzDestNotDirectory() throws Exception {
|
||||||
|
String testName = "testUnTarGzDestNotDirectory";
|
||||||
|
Path tempDir = Files.createTempDirectory("compress_test_");
|
||||||
|
try {
|
||||||
|
Path notDir = tempDir.resolve("not_a_dir.txt");
|
||||||
|
Files.writeString(notDir, "I am a file");
|
||||||
|
|
||||||
|
// 先创建一个合法tar.gz
|
||||||
|
Path sourceFile = tempDir.resolve("src.txt");
|
||||||
|
Files.writeString(sourceFile, "test");
|
||||||
|
Path tarGzFile = tempDir.resolve("test.tar.gz");
|
||||||
|
compress.MakeTarGz(sourceFile.toString(), tarGzFile.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
compress.UnTarGz(tarGzFile.toString(), notDir.toString());
|
||||||
|
assertCondition(testName + " - 应抛出异常", false);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertCondition(testName + " - 应抛出IllegalArgumentException", true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertCondition(testName + " - 异常类型不正确: " + e.getClass().getName(), false);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
deleteTempDir(tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 辅助方法 ==========
|
||||||
|
|
||||||
|
static void assertCondition(String message, boolean condition) {
|
||||||
|
if (condition) {
|
||||||
|
System.out.println("[PASS] " + message);
|
||||||
|
passed++;
|
||||||
|
} else {
|
||||||
|
System.out.println("[FAIL] " + message);
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deleteTempDir(Path dir) {
|
||||||
|
try {
|
||||||
|
Files.walk(dir)
|
||||||
|
.sorted(java.util.Comparator.reverseOrder())
|
||||||
|
.forEach(path -> {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(path);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/test/java/echo.java
Normal file
13
src/test/java/echo.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
||||||
|
|
||||||
|
public class echo {
|
||||||
|
static void main(String[] args) {
|
||||||
|
main.echo.Println("YELLOW", ColorNameEnum.YELLOW);
|
||||||
|
main.echo.Println("BLUE", ColorNameEnum.BLUE);
|
||||||
|
main.echo.Println("CYAN", ColorNameEnum.CYAN);
|
||||||
|
main.echo.Println("PURPLE", ColorNameEnum.PURPLE);
|
||||||
|
main.echo.Println("GREEN", ColorNameEnum.GREEN);
|
||||||
|
main.echo.Println("RED", ColorNameEnum.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user