diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 36f04cb..c457f0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,4 +18,10 @@ ### console-ui - 🧹重构: 重构console-ui,使用vue3.0,vite,typescript进行重构 +### FileModule +- 🎈新增: 新增 `JsonFileUtil` 工具类,用于进行json文件的读写操作 +- 🎈新增: 新增 `FileUtil` 工具类,用于进行文件复制文件删除等操作 +- 🎈新增: 新增 `FileCondition` 方法,用于对文件递归删除进行条件过滤 +- 🧪测试: 测试 `FileUtil` 工具类, 测试 `JsonFileUtil` 工具类 + diff --git a/FileModule/pom.xml b/FileModule/pom.xml index a272259..8e5c0b0 100644 --- a/FileModule/pom.xml +++ b/FileModule/pom.xml @@ -18,10 +18,20 @@ + - junit - junit - 3.8.1 + com.alibaba + fastjson + 1.2.75 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok test diff --git a/FileModule/src/main/java/org/example/App.java b/FileModule/src/main/java/org/example/App.java deleted file mode 100644 index 5f21d2e..0000000 --- a/FileModule/src/main/java/org/example/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.example; - -/** - * Hello world! - * - */ -public class App -{ - public static void main( String[] args ) - { - System.out.println( "Hello World!" ); - } -} diff --git a/FileModule/src/main/java/org/example/method/FileCondition.java b/FileModule/src/main/java/org/example/method/FileCondition.java new file mode 100644 index 0000000..70351ac --- /dev/null +++ b/FileModule/src/main/java/org/example/method/FileCondition.java @@ -0,0 +1,8 @@ +package org.example.method; + +import java.nio.file.Path; + +@FunctionalInterface +public interface FileCondition { + boolean condition(Path path); +} diff --git a/FileModule/src/main/java/org/example/util/FileUtil.java b/FileModule/src/main/java/org/example/util/FileUtil.java new file mode 100644 index 0000000..14be2f4 --- /dev/null +++ b/FileModule/src/main/java/org/example/util/FileUtil.java @@ -0,0 +1,160 @@ +package org.example.util; + +/** + * @author Genius + * @date 2023/04/20 11:03 + **/ + +import org.example.method.FileCondition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/** + * 文件工具类 + */ +public class FileUtil { + + private static Logger logger = LoggerFactory.getLogger(FileUtil.class); + /** + * 判断文件是否存在 + * @param dir 文件路径需要包含文件名 + * @return Boolean + */ + public static Boolean isFileExist(String dir){ + return new File(dir).exists(); + } + + /** + * 复制文件 比 Files更快 + * @param srcPath 源文件路径 + * @param destPath 目标文件路径 + * @return File + */ + public static File copyFile(String srcPath, String destPath) { + try( + FileChannel src = new FileInputStream(srcPath).getChannel(); + FileChannel dest = new FileInputStream(destPath).getChannel() + ){ + dest.transferFrom(src, 0, src.size()); + }catch (IOException e){ + logger.error("复制文件失败", e); + return null; + } + return new File(destPath); + } + + /** + * 删除文件 + * @param path 文件路径 + * @param filename 文件名 + * @return boolean + */ + public static boolean deleteFile(String path,String filename){ + return deleteFile(Paths.get(path,filename).toString()); + } + + /** + * 删除文件 + * @param path 文件路径 + * @return boolean + * @throws IOException IOException + */ + public static boolean deleteFile(String path){ + try { + Files.delete(Paths.get(path)); + } catch (IOException e) { + logger.error("删除文件失败", e); + return false; + } + return true; + } + + /** + * 文件目录递归删除 + * @param path 文件路径 + * @return boolean + * @throws IOException IOException + */ + public static boolean deleteDirectory(String path) throws IOException { + FileCondition condition = file -> !file.toString().startsWith("C:")||!file.toString().startsWith("root"); + return deleteDirectory0(path, condition, condition, condition); + } + + /** + * 文件目录递归删除 + * @param path 文件路径 + * @param visit 访问文件时触发该方法 + * @param preVisit 访问子目录前触发该方法 + * @param postVisit 访问目录之后触发该方法 + * @return boolean + * @throws IOException IOException + */ + public static boolean deleteDirectory(String path,FileCondition visit, FileCondition preVisit, FileCondition postVisit) throws IOException { + return deleteDirectory0(path, visit, preVisit, postVisit); + } + + /** + * 递归删除 + * @param path 文件路径 + * @return File + */ + private static boolean deleteDirectory0(String path, FileCondition visit, FileCondition preVisit, FileCondition postVisit) throws IOException { + Files.walkFileTree(Paths.get(path), new SimpleFileVisitor() { + // 在访问文件时触发该方法 + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if(!visit.condition(file)){ + logger.info("文件被跳过: {}", file); + return FileVisitResult.SKIP_SUBTREE; + } + Files.delete(file); + logger.info("文件被删除: {}", file); + return FileVisitResult.CONTINUE; + } + + // 在访问子目录前触发该方法 + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if(!preVisit.condition(dir)){ + logger.info("目录被跳过: {}", dir); + return FileVisitResult.SKIP_SUBTREE; + } + logger.info("目录被访问: {}", dir); + return FileVisitResult.CONTINUE; + } + + // 在访问目录之后触发该方法 + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if(!postVisit.condition(dir)){ + logger.info("目录被跳过: {}", dir); + return FileVisitResult.SKIP_SUBTREE; + } + Files.delete(dir); + logger.info("目录被删除: {}", dir); + return FileVisitResult.CONTINUE; + } + + // 在访问失败时触发该方法 + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + // 写一些具体的业务逻辑 + return super.visitFileFailed(file, exc); + } + + } + ); + return true; + } + +} diff --git a/FileModule/src/main/java/org/example/util/JsonFileUtil.java b/FileModule/src/main/java/org/example/util/JsonFileUtil.java new file mode 100644 index 0000000..64b86f4 --- /dev/null +++ b/FileModule/src/main/java/org/example/util/JsonFileUtil.java @@ -0,0 +1,247 @@ +package org.example.util; + +import com.alibaba.fastjson.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +/** + * @author Genius + * @date 2023/04/20 10:53 + **/ + +/** + * 操作json文件 + */ +public class JsonFileUtil { + + private static final Logger logger = LoggerFactory.getLogger(JsonFileUtil.class); + + /* ------------------read json file------------------ */ + + /** + * 读取json文件 + * @param filePath 文件路径,应该为全路径 + * @param fileName 文件名 + * @return Map 返回Map类型的数据 + */ + public static Map readJsonFile(String filePath, String fileName) { + return readJsonFile(Paths.get(filePath, fileName).toString()); + } + + /** + * 读取json文件 + * @param fullPath 文件路径,包含文件名 + * @return Map 返回Map类型的数据 + */ + public static Map readJsonFile(String fullPath){ + Map maps = null; + JSONObject jsonObject = readJsonFileToJSONObject(fullPath); + if (Objects.nonNull(jsonObject)) { + maps = jsonObject.getInnerMap(); + } + return maps; + } + + /** + * 读取json文件转为JSONObject + * @param fullPath 文件路径,包含文件名 + * @return JSONObject + */ + public static JSONObject readJsonFileToJSONObject(String fullPath){ + return readJsonFileToObject(fullPath, JSONObject.class); + } + + /** 读取json文件转为对应的类 + * @param fullPath 文件路径,包含文件名 + * @param clazz 类 + * @return T + */ + public static T readJsonFileToObject(String fullPath, Class clazz){ + T t = null; + Path dir = Paths.get(fullPath); + try{ + if (FileUtil.isFileExist(dir.toString())) { + String res = Files.readString(dir, StandardCharsets.UTF_8); + logger.info("读取json文件成功, 文件内容为: {}", res); + + t = JSON.parseObject(res, clazz); + } + }catch (Exception e){ + logger.error("读取json文件失败", e); + } + return t; + } + + /* ------------------write json file------------------ */ + + /** + * 写入json文件 + * @param filePath 文件路径,应该为全路径 + * @param fileName 文件名 + * @param data 写入Json数据 + * @return File + */ + public static File writeJsonFile(String filePath, String fileName, Map data) { + return writeJsonFile(Paths.get(filePath, fileName).toString(), data); + } + + /** + * 读取json文件 + * @param fullPath 文件路径,应该为全路径 + * @param data 写入Json数据 + * @return File + */ + public static File writeJsonFile(String fullPath, Map data) { + return writeJsonFile0(fullPath, JSON.toJSONString(data,true),true); + } + + /** + * 写入json文件,如果文件不存在则报错 + * @param filePath 文件路径,应该为全路径 + * @param fileName 文件名 + * @param data 写入Json数据 + * @return File + */ + public static File writeJsonFileIsExist(String filePath, String fileName, T data) { + return writeJsonFileIsExist(Paths.get(filePath, fileName).toString(), data); + } + + /** + * 写入json文件,如果文件不存在则报错 + * @param fullPath 文件路径,应该为全路径 + * @param data 写入Json数据 + * @return File + */ + public static File writeJsonFileIsExist(String fullPath, T data) { + return writeJsonFile0(fullPath, JSON.toJSONString(data,true),false); + } + + /** + * 将Obj写入json文件 + * @param filePath 文件路径,应该为全路径 + * @param fileName 文件名 + * @param obj 写入Json数据 + * @return File + */ + public static File writeJsonFile(String filePath, String fileName, T obj) { + return writeJsonFile(Paths.get(filePath, fileName).toString(), obj); + } + + /** + * 将Obj写入json文件 + * @param fullPath 文件路径,应该为全路径 + * @param obj 写入Json数据 + * @return File + */ + public static File writeJsonFile(String fullPath, T obj) { + return writeJsonFile0(fullPath, JSON.toJSONString(obj,true),true); + } + + /** + * 写入json文件,如果文件不存在则自动创建 + * @param fullPath 文件路径,应该为全路径 + * @param json 写入Json数据 + * @param autoCreate 是否自动创建文件 + * @return File + */ + public static File writeJsonFile0(String fullPath, String json,boolean autoCreate) { + Path dir = Paths.get(fullPath); + try{ + if(!FileUtil.isFileExist(dir.toString())&&autoCreate){ + Files.createFile(dir); + logger.info("新建文件{}",dir); + } + if (FileUtil.isFileExist(dir.toString())) { + Files.writeString(dir, json, StandardCharsets.UTF_8); + logger.info("写入json文件成功, 文件内容为: {}", json); + }else { + logger.error("写入json文件失败, 文件不存在"); + return null; + } + }catch (Exception e){ + logger.error("写入json文件失败", e); + return null; + } + return dir.toFile(); + } + + /** + * 写入大j对象到Json文件中 + * @param fullPath 文件路径,应该为全路径 + * @param data 写入Json数据 + * @return File + */ + public static File writeBigJsonFile(String fullPath, Map data) { + Path dir = Paths.get(fullPath); + try{ + if(!FileUtil.isFileExist(dir.toString())){ + Files.createFile(dir); + logger.info("新建文件{}",dir); + } + if (FileUtil.isFileExist(dir.toString())) { + JSONWriter writer = new JSONWriter(Files.newBufferedWriter(dir, StandardCharsets.UTF_8)); + writer.startObject(); + for (Map.Entry stringObjectEntry : data.entrySet()) { + String key = stringObjectEntry.getKey(); + Object value = stringObjectEntry.getValue(); + writer.writeKey(key); + writer.writeValue(value); + logger.info("写入json类成功, 类内容为: {}:{}", key, value); + } + writer.endObject(); + writer.close(); + + }else { + logger.error("写入json文件失败, 文件不存在"); + return null; + } + }catch (Exception e){ + logger.error("写入json文件失败", e); + return null; + } + return dir.toFile(); + } + + /** + * 写入大j对象到Json文件中 + * @param fullPath 文件路径,应该为全路径 + * @param Objs 写入大对象的数组 + * @return File + */ + public static File writeBigJsonFile(String fullPath, List Objs) { + Path dir = Paths.get(fullPath); + try{ + if(!FileUtil.isFileExist(dir.toString())){ + Files.createFile(dir); + logger.info("新建文件{}",dir); + } + if (FileUtil.isFileExist(dir.toString())) { + JSONWriter writer = new JSONWriter(Files.newBufferedWriter(dir, StandardCharsets.UTF_8)); + writer.startArray(); + for (T obj : Objs) { + writer.writeValue(obj); + logger.info("写入json类成功, 类内容为: {}", obj); + } + writer.endArray(); + writer.close(); + + }else { + logger.error("写入json文件失败, 文件不存在"); + return null; + } + }catch (Exception e){ + logger.error("写入json文件失败", e); + return null; + } + return dir.toFile(); + } +} diff --git a/FileModule/src/main/resources/test.json b/FileModule/src/main/resources/test.json new file mode 100644 index 0000000..2378b53 --- /dev/null +++ b/FileModule/src/main/resources/test.json @@ -0,0 +1,10 @@ +{ + "name": "ChopperBot", + "description": "A bot for the ChopperMC server", + "version": "1.0.0", + "module": { + "type": ["Account","Creeper","File","Hot","Publish","Section","SectionWork","VideoSection"], + "main": "console", + "ui": "console-ui" + } +} diff --git a/FileModule/src/test/java/org/example/bean/Student.java b/FileModule/src/test/java/org/example/bean/Student.java new file mode 100644 index 0000000..c67aded --- /dev/null +++ b/FileModule/src/test/java/org/example/bean/Student.java @@ -0,0 +1,30 @@ +package org.example.bean; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author Genius + * @date 2023/04/20 13:46 + **/ +@Data +public class Student{ + private String name; + private int age; + private String school; + private String major; + private List hobby; + private Map info; + + public Student(String name, int age, String school, String major, List hobby, Map info) { + this.name = name; + this.age = age; + this.school = school; + this.major = major; + this.hobby = hobby; + this.info = info; + } + +} diff --git a/FileModule/src/test/java/org/example/util/FileUtilTest.java b/FileModule/src/test/java/org/example/util/FileUtilTest.java new file mode 100644 index 0000000..cd0d98d --- /dev/null +++ b/FileModule/src/test/java/org/example/util/FileUtilTest.java @@ -0,0 +1,17 @@ +package org.example.util; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +/** + * @author Genius + * @date 2023/04/20 14:15 + **/ +public class FileUtilTest { + + @Test + public void testDelete() throws IOException { + FileUtil.deleteDirectory("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\trash"); + } +} diff --git a/FileModule/src/test/java/org/example/util/JsonFileUtilTest.java b/FileModule/src/test/java/org/example/util/JsonFileUtilTest.java new file mode 100644 index 0000000..3e5685c --- /dev/null +++ b/FileModule/src/test/java/org/example/util/JsonFileUtilTest.java @@ -0,0 +1,67 @@ +package org.example.util; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.JSONWriter; +import org.example.bean.Student; +import org.junit.jupiter.api.Test; +import org.junit.platform.commons.util.PackageUtils; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +/** + * @author Genius + * @date 2023/04/20 11:43 + **/ + +public class JsonFileUtilTest { + + + + @Test + public void writeClassInJsonFile() { + Student student = new Student( + "Genius", + 18, + "HUST", + "CS", + List.of("Coding", "Reading", "Playing"), + Map.of("QQ", "123456789", "WeChat", "987654321") + ); + JsonFileUtil.writeJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\", "student.json", student); + JsonFileUtil.writeBigJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\student2.json", List.of(student)); + JsonFileUtil.writeJsonFileIsExist("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\student3.json", student); + + System.out.println(JsonFileUtil.readJsonFileToObject("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\student.json", Student.class)); + System.out.println(JsonFileUtil.readJsonFileToObject("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\student2.json",List.class)); + } + + @Test + public void readJsonFile() { + Map maps = JsonFileUtil.readJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\", "test.json"); + Object test = maps.get("module"); + System.out.println(test); + System.out.println(maps); + } + + @Test + public void writeJsonFile() { + Map maps = JsonFileUtil.readJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\", "test.json"); + JsonFileUtil.writeJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\", "test2.json", maps); + JsonFileUtil.writeJsonFileIsExist("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\test2.json", maps); + } + + @Test + public void writeJsonFileByJsonWriter() throws IOException { + Map maps = JsonFileUtil.readJsonFile("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\", "test.json"); + Path dir = Paths.get("E:\\Project\\ChopperBot\\FileModule\\src\\main\\resources\\test2.json"); + JsonFileUtil.writeBigJsonFile(dir.toString(),maps); + } + +} diff --git a/console-ui/index.html b/console-ui/index.html index 0ad78f3..8c39f99 100644 --- a/console-ui/index.html +++ b/console-ui/index.html @@ -5,7 +5,7 @@ - Vuetify-Lux + ChopperBot @@ -72,12 +72,12 @@ const openGithubSite = () => { > - Yang J.K. + TML Github: - github.com/yangjiakai + github.com/TimeMachineLab