![](/img/trans.png)
[英]java bufferedReader.readLine() can't read whole file line
[英]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解析器的代碼在這里
這使我想到了兩種可能性:
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.