簡體   English   中英

為什么BufferedReader無法讀取InputStream的最后一行?

[英]why does BufferedReader fail to read the final line for an InputStream?

*注意:為澄清起見,也許這個問題在InputStream處於“活動狀態”時還不清楚。 與telnet氣象服務的連接(請參閱下面的鏈接)保持打開狀態。 目標是讓所有線路都來自服務器。*

從示例Apache WeatherTelnet 代碼構建,我正在使用InputStream.read來使用chars方法一次輸出一個字符(一個javamex教程習慣的啟發)的服務器結果:

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/Teln/dist/Teln.jar 
------------------------------------------------------------------------------
*               Welcome to THE WEATHER UNDERGROUND telnet service!            *
------------------------------------------------------------------------------
*                                                                            *
*   National Weather Service information provided by Alden Electronics, Inc. *
*    and updated each minute as reports come in over our data feed.          *
*                                                                            *
*   **Note: If you cannot get past this opening screen, you must use a       *
*   different version of the "telnet" program--some of the ones for IBM      *
*   compatible PC's have a bug that prevents proper connection.              *
*                                                                            *
*           comments: jmasters@wunderground.com                              *
------------------------------------------------------------------------------

Press Return to continue:
^Cthufir@dur:~$ 

這是所需的輸出。 但是,使用BufferedReader讀取InputStream導致刪除最后一行。 (或者,至少,它沒有打印到控制台。)輸出錯誤,使用lines方法:

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/Teln/dist/Teln.jar 

------------------------------------------------------------------------------

*               Welcome to THE WEATHER UNDERGROUND telnet service!            *

------------------------------------------------------------------------------

*                                                                            *

*   National Weather Service information provided by Alden Electronics, Inc. *

*    and updated each minute as reports come in over our data feed.          *

*                                                                            *

*   **Note: If you cannot get past this opening screen, you must use a       *

*   different version of the "telnet" program--some of the ones for IBM      *

*   compatible PC's have a bug that prevents proper connection.              *

*                                                                            *

*           comments: jmasters@wunderground.com                              *

------------------------------------------------------------------------------



^Cthufir@dur:~$ 
thufir@dur:~$ 

StreamReader代碼:

package teln;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamReader {

    private StreamReader() {
    }

    StreamReader(InputStream inputStream) throws IOException {
        lines(inputStream);
    }

    private void chars(InputStream inputStream) throws IOException {
        do {
            char ch = (char) inputStream.read();
            System.out.print(ch);
        } while (true);
    }

    private void lines(InputStream inputStream) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        String line = "";
        do {
            System.out.println(line);
        } while ((line = br.readLine()) != null);

        System.out.println(line);

    }
}

大概最后一行是“空”嗎? 可以更改邏輯,以便從lines像在chars一樣打印最后一行嗎?

您還沒有解釋數據的來源,但是我懷疑數據來自某些來源,這些來源的末尾沒有行終止符, 也沒有關閉流

如果關閉了流(例如,通過終止連接,如果這是客戶端/服務器應用程序), 則將看到最后一行。 BufferedReader肯定會返回最后一行數據,即使它沒有以行終止符結尾,也只有在知道它已經到達流的末尾時才返回。

正如Jean所提到的,如果您知道輸入永遠不會以換行符'\\n'或回車符'\\r'結束,則使用BufferReader是一個缺點。 while循環之后while您可能需要使用ready()方法來測試在最后一行讀取之后是否確實還有更多文本,並使用read()方法之一來提取剩余的文本。 或者,將另一個文本閱讀器全部替換為BufferReader。

BufferedReader#readLine()讀取流,直到它到達\\n\\r或流的末尾,返回它所讀取的內容,然后返回nullnull 您沒有向我們展示一些東西。 為什么輸出中的行之間有新行?

至於輸出末尾的null

private void lines(InputStream inputStream) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
    String line = "";
    do {
        System.out.println(line); // will print an empty line to start
    } while ((line = br.readLine()) != null);

    System.out.println(line); // will print null

}

你的循環應該是

while ((line = br.readLine()) != null) {
    System.out.println(line);
}

避免打印第一個空的。 另外,不要在while循環外打印該line 這將永遠是null ,顯然(你不會是外面while其他)。

您的chars()方法也將永遠循環。

您的服務器很有可能沒有關閉流,因此BufferedReader進行的基礎read調用不會返回-1來表示EOF。 您是在自行殺死應用程序嗎?

好的,這里出現了kudge:

package teln;

import static java.lang.System.out;
import java.io.IOException;
import java.io.InputStream;

public class StreamReader {

    private StreamReader() {
    }

    StreamReader(InputStream inputStream) throws IOException {
        printEachLine(inputStream);
    }

    private void printEachLine(InputStream inputStream) throws IOException {
        int foo = 0;
        char ch = 0;
        StringBuilder sb = new StringBuilder();
        out.println("lines..");
        boolean isEOL = false;  //err, need to set this or get rid of it
        do {
            foo = inputStream.read();
            ch = (char) foo;
            //out.print(foo);
            sb.append(ch);
            if ((ch == 10)) {
                out.print(sb);
                sb = new StringBuilder();
                foo = inputStream.read();
                ch = (char) foo;
                sb.append(ch);
                if (ch != 13) {
                    while ((255 > ch) && (ch >= 0)) {
                        sb = new StringBuilder();
                        foo = inputStream.read();
                        ch = (char) foo;
                        sb.append(ch);
                        out.print(sb);
                    }
                }
                sb.append(ch);
            }

        } while (!isEOL);

    }
}

這取決於遵循特定模式的LF和CR。 LF(10)后面總是跟着CR(13),除非它是第一行或最后一行。 因此,在這種特殊情況下,此代碼將查找丟失的CR並將其標識為需要特殊輸出。

但是,這是一個巨大的假設,可能特定於此天氣telnet服務。 此外,似乎非常脆弱。

現在,我將繼續講下去,但將繼續尋找其他答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM