2012-07-03 1 views
0

Я испытываю странную ошибку с одной из наших систем, которую я затрудняюсь объяснить. В нашей системе бэкенд генерирует выходной файл большого TSV, который мы затем подают через HTTP, используя следующий код:Возможно ли BufferedReader.readLine() не читать целую строку при чтении из медленного потока?

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(); 

Тогда на стороне клиента существует TSV анализатор потребляя ответ HTTP, но на очень больших входов мы начинаем видеть странные артефакты, в которых парсер будет сообщать о строке как о неправильном количестве элементов, а сообщение об ошибке печатает строку, которую он будет обрабатывать, и эта строка будет случайным фрагментом данных, т. е. не всей строкой данных

Моя первая мысль заключалась в том, что генерируемый TSV был искажен, но я в значительной степени решил это, скопировав файл непосредственно из бэкэнд-системы, а затем выполнив его через три независимо написанные парсером TSV с открытым исходным кодом (в том числе тот, который используется клиентским кодом), и все они способны разбирать файл при работе в локальном файле.

Для справки код для TSV синтаксического анализа мы используем это here

Это приводит меня к двум возможностям:

  1. Код, я показал для копирования файлов через HTTP испорчен в в некотором роде - в этом случае мне бы хотелось, чтобы кто-то указал на ту тупую, но неочевидную ошибку, которую я сделал!
  2. BufferedReader.readLine(), который используется компьютером-потребителем, не гарантированно считывает целые строки? Я бы не был полностью удивлен, если это так, потому что я был укушен странным поведением чтения по медленным сетевым потокам в .Net. Так интересно, может ли аналогичная проблема примениться в Java?

Или есть некоторые другие объяснения, которые я пропустил?

+2

readLine() будет блокироваться навсегда, если вы не отправите новую строку. Его общий вопрос для людей писать() текст без новой строки. –

ответ

1

В публикации этого вопроса, я вдруг заметил, что была ошибка

Следующая часть кода я вывесил для копирования файла неверен (как правило!):

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); 

проблема в том, что я всегда писал весь буфер в выходной поток, даже если мы будем читать меньше от входа, чем размер й e буфера. Это означало, что в конце файла мы будем печатать последний фрагмент данных и все остальное в остальной части буфера, следовательно, случайный фрагмент данных остался!

 Смежные вопросы

  • Нет связанных вопросов^_^