|
|
@@ -0,0 +1,134 @@
|
|
|
+package cn.reghao.bnt.web.devops.srv.service;
|
|
|
+
|
|
|
+import cn.reghao.bnt.common.model.FileTree;
|
|
|
+import cn.reghao.jutil.jdk.string.IdGenerator;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.FileVisitResult;
|
|
|
+import java.nio.file.FileVisitor;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.attribute.BasicFileAttributes;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2025-12-21 12:09:20
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class FileTreeService {
|
|
|
+ private final IdGenerator idGenerator = new IdGenerator(10, "file-id");
|
|
|
+ private final List<FileTree> list = new ArrayList<>();
|
|
|
+
|
|
|
+ void walkDir(Path path, String baseDir) throws IOException {
|
|
|
+ Files.walkFileTree(path, new FileVisitor<Path>() {
|
|
|
+ @Override
|
|
|
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
|
|
+ try {
|
|
|
+ process(dir.toFile(), baseDir);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return FileVisitResult.CONTINUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
|
+ try {
|
|
|
+ process(file.toFile(), baseDir);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return FileVisitResult.CONTINUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
|
|
|
+ return FileVisitResult.CONTINUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
|
|
+ return FileVisitResult.CONTINUE;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ void process(File file, String baseDir) {
|
|
|
+ String absolutePath = file.getAbsolutePath();
|
|
|
+ String path = absolutePath.replace(baseDir, "");
|
|
|
+ path = absolutePath;
|
|
|
+ String type = "file";
|
|
|
+ if (file.isDirectory()) {
|
|
|
+ type = "dir";
|
|
|
+ }
|
|
|
+ list.add(new FileTree(type, path));
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<FileTree> getFileTree(String baseDir) {
|
|
|
+ list.clear();
|
|
|
+ try {
|
|
|
+ walkDir(Path.of(baseDir), baseDir);
|
|
|
+ Map<String, FileTree> map = list.stream()
|
|
|
+ .collect(Collectors.toMap(FileTree::getPath, v -> v));
|
|
|
+
|
|
|
+ // 按 path 长度降序
|
|
|
+ List<String> list = map.keySet().stream()
|
|
|
+ .sorted((o1, o2) -> o2.length()-o1.length())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 对于一棵树, 从最下面的节点往上收拢
|
|
|
+ for (String path : list) {
|
|
|
+ if (path.isBlank()) {
|
|
|
+ map.remove(path);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ int idx = path.lastIndexOf("/");
|
|
|
+ String parentPath = path.substring(0, idx);
|
|
|
+ if (parentPath.isBlank()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ FileTree parent = map.get(parentPath);
|
|
|
+ if (parent == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parent.getId() == null) {
|
|
|
+ String id = idGenerator.getUuid();
|
|
|
+ parent.setId(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ FileTree fileTree = map.get(path);
|
|
|
+ fileTree.setPid(parent.getId());
|
|
|
+ if (fileTree.getId() == null) {
|
|
|
+ String id = idGenerator.getUuid();
|
|
|
+ fileTree.setId(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ parent.getChildren().add(fileTree);
|
|
|
+ map.remove(path);
|
|
|
+ }
|
|
|
+
|
|
|
+ String rootId = idGenerator.getUuid();
|
|
|
+ List<FileTree> tree = new ArrayList<>(map.values());
|
|
|
+ for (FileTree fileTree : tree) {
|
|
|
+ fileTree.setPid(rootId);
|
|
|
+ if (fileTree.getId() == null) {
|
|
|
+ String id = idGenerator.getUuid();
|
|
|
+ fileTree.setId(id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tree;
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+}
|