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ソースファイルに次のようなすべてのデータを追加したいと思います。

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

source_files括弧で囲まれています。また、clone_pairsについても同じことで、括弧で囲まれたすべてのデータをarrayListclonePairsに追加します。

これは私がこれまでに行ったことです...しかし、それは機能していません。

    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

すべての人の利益のために、これはAndrewSolutionCodeによって提案された正しいコードです。

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

whileの本体にif/elseを使用したアプローチは、単なるオーバーヘッドだと思います。チェックしているすべてのループについて:1。whileループ内の条件2.ループ内の他のすべての場合。次に、たとえば「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 に答える