1

我想读取文本文件中的某些部分并将这些部分中的每一个添加到它们相应的 ArrayList 中。这是一个示例文本文件:

format: pair_diploid
option: -b 50
option: -pp +
option: -mr masked
option: -n C:\Users\Fertilak\gimp\gimp
preprocess_script: cpp
source_files {
1   types.h 1
2   actions.c   2316
3   actions.h   1
4   editor-actions.c    91
5   editor-actions.h    1
287 test-clipboard.c    1247
}
source_file_remarks {
42
:   masked
152
:   masked
170
:   masked
}
clone_pairs {
5545    56.0-180    148.0-180
3083    62.1959-2107    62.2107-2255
3083    62.2107-2255    62.1959-2107
89  82.0-520    82.620-1140
89  82.620-1140 82.0-520
5545    148.0-180   56.0-180
12084   2865.633-694    2868.2877-2938
12084   2868.2877-2938  2865.633-694
}
clone_set_remarks {
}

我想在我的 2 ArrayList 中添加的部分在 source_files 和 clone_pairs 中用括号“{}”括起来。因此,例如,我想在 arraylist sourcefiles 中添加所有数据,例如

    1   types.h 1
    2   actions.c   2316
...etc

它们包含在 source_files 括号中。对于 clone_pairs 也是一样的,我会将括号中的所有数据添加到 arrayList clonePairs。

这是我到目前为止所做的......但它不起作用。

    public void readFile(String file){
List<String> sourceFiles = new ArrayList<String>();
List<String> clonePairs = new ArrayList<String>();

            try{
                BufferedReader buff = new BufferedReader(new FileReader(file));
                
                try{
                    
                    String readBuff = buff.readLine();
                    while (readBuff != null){
                        if (readBuff.equals("source_files {") && !readBuff.equals("}")){
                            sourceFiles.add(readBuff);
                               }

                    else if (readBuff.equals("clone_pairs {") && !readBuff.equals("}")){
                            clonePairs.add(readBuff);
                               }

                        readBuff = buff.readLine();
                    }
                }
                finally{
                    buff.close();
                    }
            }
            
            catch(FileNotFoundException e){
                System.out.println("File not found");
            }
            catch(IOException e){
                System.out.println(e);
            }
            
        }

除了 if-else 条件之外,几乎所有代码都在这段代码中工作。关于如何做到这一点的任何建议?

编辑

我已经编辑了内容并将其替换为 readBuff 字符串。对不起

编辑 2

为了大家的利益,这是 Andrew Solution Code 提出的正确代码:

public void readFile(String file){
        try{
            BufferedReader buff = new BufferedReader(new FileReader(file));
            
            try{
                
                String readBuff = buff.readLine();
                String section = "";
                while (readBuff != null){
                    if (section.equals("source_files {") && !readBuff.equals("}")){
                        sourceFiles.add(readBuff);
                    } else if (section.equals("clone_pairs {") && !readBuff.equals("}")){
                        clonePairs.add(readBuff);
                    } else if (readBuff.equals("source_files {") || readBuff.equals("clone_pairs {")) {
                        section = readBuff;
                    } else if (readBuff.equals("}")) {
                        section = "";
                    }

                    readBuff = buff.readLine();
                }

            }
            finally{
                buff.close();
                }
        }
        
        catch(FileNotFoundException e){
            System.out.println("File not found");
        }
        catch(IOException e){
            System.out.println("exceptional case");
        }
    }
4

2 回答 2

3

您正在构建的东西称为状态机。你需要一些东西来跟踪你在文件中的位置——状态。我已经调用它了section

                String readBuff = buff.readLine();
                String section = "";
                while (readBuff != null){
                    if (section.equals("source_files {") && !readBuff.equals("}")){
                        sourceFiles.add(readBuff);
                    } else if (section.equals("clone_pairs {") && !readBuff.equals("}")){
                        clonePairs.add(readBuff);
                    } else if (readBuff.equals("source_files {") || readBuff.equals("clone_pairs {")) {
                        section = readBuff;
                    } else if (readBuff.equals("}")) {
                        section = "";
                    }

                    readBuff = buff.readLine();
                }
于 2012-08-31T16:22:13.773 回答
1

我认为 if/else 在 while 正文中的方法只是简单的开销。因为对于您要检查的每个循环: 1. while 循环中的条件 2. 循环中的每个 if else。然后,当您遇到例如“source_files {”时,您仍在检查所有这些条件的每个循环。

在任何情况下,您都必须阅读文件的每一行,如果您知道它们的定义顺序,那么这应该更有效:

此方法将使 BufferedReader 开始。

private BufferedReader getBufferedReader(File file) {
    try{
        return new BufferedReader(new FileReader(file));
    }
    catch(FileNotFoundException e){
        e.printStackTrace();
    }
}

此方法将读取缓冲区的每一行,直到遇到起始字符串。然后它将每下一行添加到列表中,直到遇到右括号。并将返回您新制作的清单。

private List<String> readContent(BufferedReader buff, String start) {
    List<String> list = new ArrayList<String>();
    try {
        String readBuff;
        do {
            readBuff = buff.readLine();
        }
        while (readBuff != null && !readBuff.startsWith(start));

        do {
            readBuff = buff.readLine();
            list.add(readBuff);
        }
        while (readBuff != null && !readBuff.startsWith("}"));

    }
    catch(IOException e){
        e.printStackTrace();
    }
    return list;
}

最终你的方法看起来像这样。

    public void readLists(File file) {
        BufferedReader buff = getBufferedReader(file);
        List<String> sourceFiles = readContent(buff,"source_files {");
        List<String> clonePairs = readContent(buff,"clone_pairs {");
    }

这段代码基本上在 while 循环中直接读取文件的每一行,因此您不需要任何 if/else。

如果您不知道文件中数据的顺序,则只需要 if/else。因此,此代码假定 source_files 先出现,然后 clone_pairs 出现。

另外,我使用startsWith,因为括号后可能有一个空格,即“source_files {”,这会使等号失败。

于 2012-08-31T16:45:52.063 回答