2014-03-14 177 views
0

我已經編寫了用於讀取Java中的結構化文件並提取行內容以創建對象(Person類型)的代碼。閱讀Java中的結構化文件

該文件具有以下結構:[personNumber],[PERSONNAME],[人士],例如

0,福爾摩斯,44

1,哈利波特,17

2 ,傑克斯派洛,50

...

文件進行讀取和提取信息的代碼是:

 RandomAccessFile rf = new RandomAccessFile(fileName, "rw"); 
     String line; 
     File myFile = new File(fileName); 
     scan = new Scanner(myFile); 
     String[] split; 

     //Read file 
     while((line = rf.readLine()) != null) { 
        split = scan.nextLine().split(", "); 
        pnumber = Integer.parseInt(split[0]); 
        name = split[1]; 
        age = Integer.parseInt(split[2]); 
        thePerson = new Person(name, age, pnumber); 
        personList.addLast(thePerson); 
     } 

這很好,並且Person對象被正確添加到我編程的單個鏈接列表中。這裏沒有問題。

但是,程序也應該能夠閱讀以下格式的文本文件:

#People

0,福爾摩斯,44

1,哈利波特,17

2,傑克斯派洛,50

#Dogs

0,史,10

1,米盧,7

2,疤痕,15

有一種方法,以檢查是否正被讀取的行包含一個井號(#)符號,其中該計劃的理解是不是要分割這條線,而只是開始一個新的分類?這樣,您就可以根據以下幾行來決定要創建哪種類型的對象,例如人物和狗的對象。爲了簡單起見,類型(Person,Dog)的順序將始終相同,但每個類別後面的行數會有所不同。因此,我需要幫助確定一行是否包含#符號,表示新類別的開始,並且只從以下行創建對象。

+0

呃,爲什麼使用純文本,而不是數據的文本格式,例如,比方說,JSON? – fge

回答

1

,或者如果你#總是在字符串的開頭:

編輯

while((line = rf.readLine()) != null) { 
    if(line.charAt(0)=='#'){ 
     scan.nextLine(); //use it to suit your need.. 
     //alert the program to prepare for new type of object 
     //do something.. 
    }else { 
     split = scan.nextLine().split(", "); 
       pnumber = Integer.parseInt(split[0]); 
       name = split[1]; 
       age = Integer.parseInt(split[2]); 
       thePerson = new Person(name, age, pnumber); 
       personList.addLast(thePerson); 
    } 
} 
+0

謝謝,我已經試過了。然而,看起來程序並沒有讀取包含散列符號的起始行之後的下一行。 我得到一個NumberFormatException:對於輸入字符串「#Person」,而不是跳到下一行。 – northerner

+0

也許你忘了把'split = scan.nextLine();'放在該部分,請看我的更新.. –

+0

謝謝!必須將其更改爲line = scan.nextLine();因爲split是一個數組,但是這種方式起作用! – northerner

1

由於這看起來像家庭作業,我只會回答你的第一個問題,並讓你找出如何在你的程序中使用它。檢查如果你看過行包含一個哈希符號的方法是這樣的:

line = scan.nextLine(); 
if(line.contains('#')){ 
    // the line had a # 
} 
else{ 
    //it did not. 
} 
1

您可以做到這一點:

String line = null; 
String currentType = null; 
while((line = rf.readLine()) != null) { 
    if (line.startsWith("#")) { 
     currentType = line.substring(1); 
     continue; 
    } 
    split = line.split(","); 
    if (currentType.equals("People")) { 
     pnumber = Integer.parseInt(split[0]); 
     name = split[1]; 
     age = Integer.parseInt(split[2]); 
     thePerson = new Person(name, age, pnumber); 
     personList.addLast(thePerson); 
    } else if (currentType.equals("Dogs")) { 
     ... 
     Dog dog = new Dog(name,age); 
    }   
} 
1

冷杉噸readed線分配給一個變量:

String line = scan.nextLine(); 

然後應用邏輯以它的值:

if (line.startsWith("#")) { 
    // check which type of object is declared 
} else { 
    // parse line according to object type 
    // add object to list 
} 

此外,我建議使用單獨的解析器,用於單獨的類型的對象。即DogLineParser,PersonLineParser等,所有這些都將實現通用接口。例如接口可能看起來像這樣

public interface LineParser<T> { 
    T parseLine(String line); 
} 

與示例實現看起來是這樣的:

public class PersonLineParser extends LineParser<Person> { 
    @Override 
    public Person parseLine(String line) { 
     String[] split = line.split(", "); 
     pnumber = Integer.parseInt(split[0]); 
     name = split[1]; 
     age = Integer.parseInt(split[2]); 
     return new Person(name, age, pnumber); 
    } 
} 
0
while (scanner.hasNextLine()) { 
     String line = scanner.nextLine(); 
     if(line.startsWith('#')) { 
      // don't split the 
     } 
     else { 
      // you can split 
     } 
    } 
    scanner.close();