簡體   English   中英

從慢速流讀取時,BufferedReader.readLine()是否可能不讀取整行?

[英]Is it possible for BufferedReader.readLine() to not read a whole line when reading from a slow stream?

我的一個系統遇到一個奇怪的錯誤,我不知所措。 在我們的系統中,后端生成一個大的TSV輸出文件,然后我們使用以下代碼在HTTP上提供該文件:

    BufferedInputStream input = new BufferedInputStream(p.getInputStream(), (int)FileUtils.BYTES_PER_MEGABYTE * 16);
    OutputStream output = resp.getOutputStream();
    byte[] buffer = new byte[(int) (FileUtils.BYTES_PER_KILOBYTE * 8)];
    do
    {
        int read = input.read(buffer);
        if (read <= 0) break;
        output.write(buffer);           
    } while (true);
    input.close();
    output.close();

然后在客戶端,有一個使用HTTP響應的TSV解析器,但是在非常大的輸入上,我們開始看到奇怪的工件,其中解析器將報告一行錯誤的項目數,並且錯誤消息會打印將要解析的行,該行將是隨機數據塊,即不是整個數據行

我最初的想法是生成的TSV格式錯誤,但是我已經通過直接從后端系統復制文件,然后通過三個獨立編寫的開放源代碼TSV解析器(包括客戶端代碼正在使用的解析器)運行該文件,將其排除在外),當它們在本地文件上運行時,所有文件都能夠很好地解析文件。

供參考,我們使用的TSV解析器的代碼在這里

這使我想到了兩種可能性:

  1. 我顯示的用於通過HTTP復制文件的代碼在某些方面存在缺陷-在這種情況下,我希望有人指出我犯了什么愚蠢但不明顯的錯誤!
  2. 不能保證使用解析器正在使用的BufferedReader.readLine()能讀取整行嗎? 如果是這種情況,我將不會完全感到驚訝,因為我在.Net緩慢的網絡流中被奇怪的讀取行為所困擾,所以想知道類似的問題是否可以在Java中解決?

還是我忽略了其他解釋?

在發布這個問題時,我突然發現了錯誤所在(通常是!)。

我發布的用於復制文件的代碼的以下部分不正確:

int read = input.read(buffer);
if (read <= 0) break;
output.write(buffer);

而是應如下所示:

int read = input.read(buffer);
if (read <= 0) break;
output.write(buffer, 0, read);

問題是,即使我們從輸入中讀取的內容少於緩沖區的大小,我也總是將整個緩沖區寫入輸出流。 這意味着在文件末尾,我們將打印數據的最后一塊以及緩沖區其余部分中剩下的所有內容,因此將剩下隨機的數據塊!

暫無
暫無

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

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