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);