首页 > 解决方案 > 如何在 Java 中读取树结构制表符分隔的 txt 文件

问题描述

我正在尝试读取.txt具有带有标签的树结构的文件,并且我想将其转换为.csv.

Category
  Subcategory
     Subcategory1
        Subcategory11
            Item1
            Item2     
        Subcategory12
            Item1
        Subcategory13
            Item1
                Item11

我想创建一个.csv具有结构的文件

Category, Subcategory,Subcategory1, Subcategory11,Item1
Category, Subcategory,Subcategory1, Subcategory11,Item2 
Category, Subcategory,Subcategory1, Subcategory12,Item1
Category, Subcategory,Subcategory1, Subcategory13,Item1,Item11

到目前为止我所做的是

public static void main(String[] args) throws IOException {
    Scanner keywords = new Scanner(new File("keywords.txt"));

     ArrayList<ArrayList<String>> keywordsList = new ArrayList<ArrayList<String>>();
     ArrayList<String> newline = new ArrayList<String>();
        while(keywords.hasNext()){
            String line = keywords.nextLine();
            String[] tokens = line.split("\t");
            for(int i=0; i<tokens.length; i++){

                    if(tokens[i] != null && !tokens[i].isEmpty()){
                        newline.add(tokens[i]);
                    }
            }

            keywordsList.add(newline);

        }

}

标签: javatreeexport-to-csvcsv

解决方案


这应该可以工作(警告:它可能会因意外输入而失败,即一行比前一行多 2 个制表符):

    Scanner keywords = new Scanner(new File("keywords.txt"));

    ArrayList<String> stack = new ArrayList<String>();
    ArrayList<String> csvLines = new ArrayList<String>();

    // stores the number of elements of the last line processed
    int lastSize = -1;

    while (keywords.hasNext()) {
        String line = keywords.nextLine();

        int tabs = 0;
        // Count tabs of current line
        while (line.length() > tabs // to avoid IndexOutOfBoundsException in charAt()
                && line.charAt(tabs) == '\t') {
            tabs++;
        }

        line = line.substring(tabs); // delete the starting tabs

        if (tabs <= lastSize) {
            // if the current line has the same number of elements than the previous line, 
            // then we can save the previous processed line as CSV 
            String csvLine = "";
            for (String element : stack) {
                if (csvLine.length() > 0) {
                    csvLine += ", ";
                }
                csvLine += element;
            }
            csvLines.add(csvLine);
        }

        // if the current line has less tabs than the previous, then cut the stack 
        for (int i = stack.size() - 1; i >= tabs; i--) {
            stack.remove(i);
        }

        // if the current line has more tabs than the previous, then add the new element to the stack
        if (tabs >= stack.size()) {
            stack.add(line);
        }

        // save the number of tabs of the current line
        lastSize = tabs;
    }
    keywords.close();

    // we have to save the last line processed
    if (lastSize >= 0) {
        // save line
        String csvLine = "";
        for (String element : stack) {
            if (csvLine.length() > 0) {
                csvLine += ", ";
            }
            csvLine += element;
        }
        csvLines.add(csvLine);
    }

    // print out CSV
    for (String string : csvLines) {
        System.out.println(string);
    }

推荐阅读