如何将包含项目结构的word文档解析为文件路径数组

问题描述 投票:0回答:1

如何将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 片段。

java arrays parsing
1个回答
0
投票

读取目录结构的最佳方法是通过递归。因此,您可以实现递归算法或采用逻辑适合递归方法的数据结构(堆栈)。

在我的实现中,我更喜欢后者,每次遇到新元素时,都会将其推送到堆栈顶部。然而,每当我们停留在同一级别或追溯到

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]);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.