2014-04-02 74 views
0

所以我試圖從txtfile中提取一段代碼,該段的開始由「#EMPIRES」指示,並且結尾由以「#」開始的另一個字符串指示。然而,我的程序從來沒有找到一塊的開始,並繼續前進,直到它到達文件的末尾。爲什麼不完整閱讀文本文件?

試圖找出問題所在,我首先嚐試打印找到的每一行。 在這裏我遇到了另一個問題。我的代碼早在 甚至到達「#EMPIRES」之前就已經停止查找新行。

public String getEmpirestxt(String fileName) { 
    Scanner sc; 
    try { 
     sc = new Scanner(new File(fileName)); 
     String currentLine = sc.nextLine(); 
     StringBuilder empiresText = new StringBuilder(currentLine); 
     while (!currentLine.startsWith("# EMPIRES")) { 
      currentLine = sc.nextLine(); 
      System.out.println(currentLine); 
     } 
     currentLine = sc.nextLine(); 
     while (sc.hasNextLine() && currentLine.charAt(0)!='#') { 
      empiresText.append("\n").append(sc.nextLine()); 
     } 
     return empiresText.toString(); 
    } catch (FileNotFoundException ex) { 
     System.out.println("Landed_Titles.txt not found."); 
    } 
    return null; 
} 

文本文件本身: https://www.wetransfer.com/downloads/a1093792d5ac54b6ccce04afecb9357f20140402095042/505fca

+0

您可以嘗試註釋掉「currentLine = sc.nextLine();」嗎?看看它是否有效。 – Boris

+0

由於沒有任何變化,我在第一個循環中陷入困境... – BURNS

+1

[Java掃描程序不通過整個文件]可能的重複(http://stackoverflow.com/questions/8330695/java-scanner-not-going-通過整個文件) –

回答

1

這裏是我的問題的解決方案。我使用newBufferedReader而不是Scanner來讀取文件。本例將Java 7中

public String getEmpirestxt2(String fileName) { 
    Charset charset = Charset.forName("ISO-8859-1"); 
    Path filePath = Paths.get(fileName); 
    try (BufferedReader reader = Files.newBufferedReader(filePath, charset)) { 
     String line = null; 

     // find the start of the piece 
     while ((line = reader.readLine()) != null && !line.equals(START)) { 
     } 
     System.out.println("START: " + line); 

     // getting the piece 
     StringBuilder sb = new StringBuilder(); 
     while ((line = reader.readLine()) != null && !line.startsWith(END)) { 
      sb.append(line); 
     } 
     System.out.println("END: " + line); 

     return sb.toString(); 
    } catch (IOException x) { 
     System.err.format("IOException: %s%n", x); 
    } 
    return null; 
} 

的方法中的常數是:

private static final String START = "# EMPIRES"; 
private static final String END = "#"; 

我對您的文件測試,它工作正常。它還打印所需部分的起點和終點:

START: # EMPIRES 
END: #  color={ 144 80 60 } 
+0

你的代碼工作,所以THX! :)剩下的一個問題是,在你的第一個循環中沒有任何東西,你怎麼沒有陷入永恆的循環? – BURNS

+0

在第一個while循環中,它只是逐行讀取文件。因爲它是空的,我們簡單地忽略這些行。最終讀者會找到START並退出循環。這是迭代的條件:!line.equals(START)。當我們點擊START時,這個條件變成錯誤,我們退出循環。 – Boris

+0

那麼while控制結構會自動進入下一行? – BURNS

1
String currentLine = sc.nextLine(); 

你開始從下一行讀取。

+0

該問題位於第一whileloop,因爲我沒有與您發佈的代碼錯誤。 – BURNS

+0

沒有編譯時或運行時錯誤..這是一個邏輯錯誤。nextline從下一行讀取..所以最初你是從第二行比較 – stinepike

0

條件:

while (sc.hasNextLine() && currentLine.charAt(0)!='#') 

可以終止,因爲第二斷言,即使該文件有更多的行來讀取。如果currentLine.charAt(0)!='#'fales,則while循環結束。這並不意味着沒有更多的行要閱讀。

0

在你的第二個while循環,你永遠不會設置currentLine

這一部分:

currentLine = sc.nextLine(); 
while (sc.hasNextLine() && currentLine.charAt(0)!='#') { 
    empiresText.append("\n").append(sc.nextLine()); 
} 

應該是:

do{ 
    currentLine=sc.nextLine(); 
    empiresText.append("\n").append(sc.nextLine()); 
}while(sc.hasNextLine() && currentLine.charAt(0)!='#'); 

否則,行權後#EMPIRES將不會被讀取和代碼while循環將永遠不會停止,因爲currentLine沒有得到更新。

+0

有道理,但由於我的代碼甚至無法訪問「#EMPIRES」啓動的部分,所以我無法測試您的解決方案。 – BURNS

0

追加currentLine代替sc.nextLine()在第二個while循環:

while (sc.hasNextLine() && currentLine.charAt(0) != '#') { 
    empiresText.append("\n").append(currentLine); 
    currentLine = sc.nextLine(); 
} 

否則,你可以使用一個循環象下面這樣:

while (sc.hasNextLine()){ 
    if(sc.nextLine().startsWith("# EMPIRES")){ 
     currentLine = sc.nextLine(); 
     while (sc.hasNextLine() && currentLine.charAt(0) != '#') { 
      empiresText.append("\n").append(currentLine); 
      currentLine = sc.nextLine(); 
     } 
    } 
} 
+0

如果最後一行以'#EMPIRES'開頭,那麼怎麼辦?在這種情況下'sc.nextLine()'會返回什麼? – Braj

+0

@Rishav:沒有工作,只有一條線出來了。第一個 – BURNS