2014-11-20 71 views
2

我試圖將純文本文件解析爲ObjectsArrayList。問題是它有某種嵌套結構。數據看起來像這樣:使用嵌套結構解析純文本文件

S 183166621 75783-29-8   0 -1 0 0 0 0 
SS 183166621 0 DE Siloxane und Silikone, di-Me, polymers mit bor oxid (B2O3) 
SS 183166621 0 EN Siloxanes and Silicones, di-Me, polymers with boron oxide (B2O3) 
S 183166624 3087-36-3  221-410-8 0 -1 0 0 0 0 
SS 183166624 0 DE Titan(4+)ethanolat 
SS 183166624 0 EN Ethanol, titanium(4+) salt 

所以有一個以「S」開頭的行代表某種物質。每個「S」行後面都有多個「SS」行,其中包含不同語言的相應物質的同義詞。同義詞的數量不固定。有的只有2個,有的有3,4個或更多。

我的想法是創建一個Substance Object其中包含所有可能的同義詞列表。

我創建了一個BufferedReader並嘗試通過線

String line; 
while((line = br.readLine()) != null) { 
    if (line.startsWith("S\t")) { 

     Substance substance = new Substance(); 
     String[] columns = line.split("\t"); 

     // Parse columns and store them in substance Object 

    } 
} 

解析文件行改爲我想開始第二內環解析開始「SS」的所有行的同義詞。當到達另一個「S」行時,內循環停止。

String line; 
while((line = br.readLine()) != null) { 
    if (line.startsWith("S\t")) { 

     Substance substance = new Substance(); 
     String[] columns = line.split("\t"); 

     // Parse columns and store them in substance Object 

     while((line = br.readLine()) != null) { 
      if (line.startsWith("SS\t")) { 
       Synonym synonym = new Synonym(); 

       // Parse columns and store them in synonym Object 

       // Add synonym to List of Synonyms of Substance 
       substance.addSynonym(synonym); 
      } 
      else { 
       break; 
      } 
     } 
    } 
} 

問題與此是,在離開內循環後外環執行另一readline()所以實際的「S」 - 行丟失。

難道有人指着我正確的方向嗎?

回答

3

您已經認識到的問題是您從閱讀器讀了兩次。我只讀一次並立即分割,檢查第一個標記是主要物質的S還是先前讀取的主要物質的同義詞SS。爲此,您需要在循環外部有Substance substance;變量。

String line; 
Substance actualSubstance = null; 
while((line = br.readLine()) != null) { 
    String[] columns = line.split("\t"); 
    if (columns[0].equals("S")) { 
     actualSubstance = new Substance(); 
     // parse main substance 
    } else if (columns[0].equals("SS")) { 
     if(actualSubstance != null) { 
      Synonym synonym = new Synonym(); 
      // parse synonim substance and add to actual main substance 
      actualSubstance.addSynonym(synonym); 
     } else { 
      // bad format of the input file -> handle accordingly 
     } 
    } else { 
     // junk 
    } 
} 
1

解決此問題的常用方法之一是保留引用您創建的最後一個物質對象的引用變量。您可以在循環外定義變量。

然後你開始解析這些行。

如果該行以單個S開頭,則檢查以前的值substance是不是null。如果是這樣,請將其添加到物質清單中。然後創建一個新的Substance並將其分配給substance

這樣,你開始你打一個S線新Substance每一次,你把它在列表中,只要你看到一個新的S線。

在同一個循環中,如果行以SS開頭,則解析同義詞,並使用substance.addSynonym。你知道在這個階段你已經創建了Substance對象,它正在等待substance。如果您不確定文件是否始終以S開頭,則建議您檢查null

最後,循環結束後,你有一個substance對象Substance尚未提交到列表中,因爲沒有新的S線。您應該簡單地將它添加到列表中。

ArrayList<Substance> list = new ArrayList<>(); 
String line; 
Substance substance = null ; 

while((line = br.readLine()) != null) { 

    if (line.startsWith("S\t")) { 

     if (substance != null) { 
      list.add(substance); 
     } 

     substance = new Substance(); 
     String[] columns = line.split("\t"); 

     // Parse columns and store them in substance Object 

    else if (line.startsWith("SS\t")) { 
     Synonym synonym = new Synonym(); 

     // Parse columns and store them in synonym Object 

     // Add synonym to List of Synonyms of Substance 
     if (substance != null) { 
      substance.addSynonym(synonym); 
     } 
    } 
} 
list.add(substance);