2017-03-20 131 views
10

讀取一行文本。一條線被換行符('\ n'),一個回車符('\ r')或一個回車符緊跟着一個換行符被認爲是終止的.------ javadoc 1.8爲什麼BufferedReader.readLine可以讀取沒有行分隔符的行

然後,我有一個文本文件是這樣的:

the first line 
the second line 

注:的seond行的最後一個字符是「E」是說有不存在回車。

那麼這裏是我的演示代碼。

public void process() throws IOException{ 
    BufferedReader br = new BufferedReader(new FileReader("demo.txt")); 
    String line; 
    while((line=br.readLine())!=null){ 
     System.out.println(line); 
    } 
    br.close(); 
} 

實際輸出:

the first line 
the second line 

那麼我的問題是,爲什麼ReadLine方法可以得到第二線它沒有行分隔符(\ n或\ r或\ n \ r )。
我知道有一個文件結尾(EOF),但它似乎是javadoc不告訴EOF也是明確的行分隔符。

如果我用掃描儀代替BufferedReader中的如下代碼:

public void testScan() throws IOException{ 
    Scanner scan = new Scanner(new FileInputStream("demo.txt")); 
    String line; 
    while((line=scan.nextLine())!=null){ 
     System.out.println(line); 
    } 
    scan.close(); 
} 

那麼輸出將是:

the first line 
the second line 
Exception in thread "main" java.util.NoSuchElementException: No line found 
    at java.util.Scanner.nextLine(Scanner.java:1540) 
    at com.demo.Demo.testScan(Demo.java:39) 
    at com.demo.Demo.main(Demo.java:49) 

回答

9

因爲它編程的方式。

真的,這是該方法的用戶想要的。如果最後一行在結尾處缺少一個行分隔符,它將讀取直到EOF,這樣就不會丟失任何數據。由於缺少行分隔符,您不想丟失整行。

實際上所有類似的功能都以相同的方式工作。例如,如果您正在查看C庫中的fgets()函數,它也將以這種方式工作。 Python中的f.readline()也是如此。

編輯:掃描程序的工作方式也類似,但不同之處在於掃描程序引發異常,而當讀取所有行時BufferedReader返回null。

9

它似乎javadoc不告訴EOF也是明確的分行 。

我想你混淆行分隔符行終止

線條分隔線只是將線條彼此分開。給定一個分隔線;和輸入one;two;three,你會得到線one,twothree。但是,給定相同的字符和輸入,但是;是行終止符,因爲最後一行沒有終止,所以您會收到行onetwo

實際上,這意味着如果EOF真的是一個行分隔符,你會得到額外的數據。由於EOF在技術上不是角色,而是文件結束的條件,因此將EOF作爲行分隔符會產生很大的後果。

然而,鑑於javadoc

讀取一行文本。一條線被換行符('\ n'),回車符('\ r')或回車符 中的任意一個 被認爲是由一個換行符緊接。

我覺得術語也有誤用。要麼javadoc應該談論分離而不是終止,它應該提到EOF作爲終止該行的條件之一,或者實現不應該將最後一個視爲單獨的行。

Wikipedia

兩種方式查看換行,這兩者都是自洽的,是 換行符無論是單獨的行或他們終止線。如果一個 換行符被認爲是一個分隔符,那麼 文件的最後一行之後將不會有換行符。如果文件沒有被換行符終止,某些程序在處理文件的最後一行 時會出現問題。在其他 手中,期望換行符被用作分隔符的程序將 將最終換行符解釋爲開始一個新的(空)行。相反,如果換行符被認爲是終止符,則 ,包括 最後一行的所有文本行都將被換行符終止。如果文本文件中的最後一個 字符序列不是換行符,則最後一行 該文件可能被認爲是不正確或不完整的文本行 或該文件可能被認爲是不正確的截斷。

因此它看起來似乎readLine()有這些混合起來。

IMO readLine()的Javadoc應該這樣說:

直線被認爲由換行 (「\ n」)中的任何一個在文件或 的端部將被終止,滑架返回('\ r'),或者立即通過換行跟回 。

或針對位更含糊的表達,類似於Scanner.nextLine() says

此方法返回[..]電流線,在端

排除任何線 分離器除此之外,它將返回null當文件的結尾是唯一的輸入剩下。

相關問題