如何将word文档中提供的项目结构转换为java中的有效文件路径数组。
例如: 输入:
test-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ ├── com.company.test/
│ │ │ │ ├── controller/
│ │ │ │ │ ├── TestController.java
│ │ │ │ ├── model/
│ │ │ │ │ ├── Test.java
│ │ │ │ ├── repository/
│ │ │ │ │ ├── TestRepository.java
│ │ │ │ ├── service/
│ │ │ │ │ ├── TestService.java
│ │ │ ├── Application.java
│ │ ├── resources/
│ │ │ ├── application.properties
│ ├── test/
│ │ ├── java/
│ │ │ ├── com.company.Test/
│ │ │ │ ├── controller/
│ │ │ │ ├── service/
│ │ │ │ ├── repository/
├── pom.xml
输出:
String[] output = ["test-app/src/main/java/com/company/test/controller/TestController.java", "test-app/src/main/java/com/company/test/service/TestService.java", "test-app/src/main/java/com/company/test/model/Test.java", "test-app/src/main/java/com/company/test/repository/TestRepository.java",..............]
用于解析单词 doc 并获取字符串数组形式的结构的 java 片段。
读取目录结构的最佳方法是通过递归。因此,您可以实现递归算法或采用逻辑适合递归方法的数据结构(堆栈)。
在我的实现中,我更喜欢后者,每次遇到新元素时,都会将其推送到堆栈顶部。然而,每当我们停留在同一级别或追溯到
n+1
级别时,最后的 n+1
元素就会从堆栈中删除。在之前的文章n+1
中,n
是我们要追溯的级别数,而1
是需要用当前级别替换的上一个当前级别。例如,当迭代 controller/
中的元素 service/
和 com.company.Test/
时,我们回溯到 0 个级别,但我们需要删除前一个当前级别 controller/
为当前级别 service/
腾出空间.
public class Main {
public static void main(String[] args) throws URISyntaxException, IOException {
String[] paths = readFile("test.txt");
Arrays.stream(paths).forEach(System.out::println);
}
public static String[] readFile(String fileName) throws URISyntaxException, IOException {
List<String> paths = new ArrayList<>();
String line, pathSegment, preNameSep = " ";
char levelSign1 = '│', levelSign2 = '├';
long levelCounter = 0, lastLevel = -1;
Deque<String> stack = new ArrayDeque<>();
File file = Paths.get(Thread.currentThread().getContextClassLoader().getResource("test.txt").toURI()).toFile();
try (FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr)) {
line = br.readLine();
while (line != null) {
//Skipping to the next line if the current one is empty
if (line.isBlank()) {
line = br.readLine();
continue;
}
//Counting the current nesting level
levelCounter = line.chars().filter(c -> c == levelSign1 || c == levelSign2).count();
//If we're on the same level or going up, then we save the last path being built
if (levelCounter <= lastLevel) {
//Joining the segments in the stack into a path and adding the path to the result list (since the elements are in an ArrayDeque we need to invert them)
paths.add(StreamSupport.stream(Spliterators.spliteratorUnknownSize(stack.descendingIterator(), Spliterator.ORDERED), false).collect(Collectors.joining()));
//Removing the last n segments from the stack, where n is the number of levels we went back plus one (the current one)
for (int i = 0; i < (lastLevel - levelCounter) + 1; i++) {
stack.pop();
}
}
//Reading the name of the current path segment
pathSegment = line.contains(preNameSep) ? line.substring(line.lastIndexOf(preNameSep)).trim() : line.trim();
//Pushing the last segment on top of the stack
stack.push(pathSegment);
//Updating the level with the current one
lastLevel = levelCounter;
//Reading the next line
line = br.readLine();
}
}
return paths.toArray(new String[0]);
}
}