Прочитайте строку текста из входного потока в Java, сохраняя символ (-и) завершения строки

У меня есть этот код в Java:

InputStreamReader isr = new InputStreamReader(getInputStream());
BufferedReader ir = new BufferedReader(isr);
String line;
while ((line = ir.readLine()) != null) {
 //do stuff with "line"
}

Если входной поток содержит следующее: "hello\nhey\ryo\r\ngood-day", тогда на каждой итерации будет следовать строка:

  • привет
  • эй
  • лет
  • хороший день

Я хочу читать по одной строке за раз, но я хочу сохранить символ окончания строки:

  • привет\п
  • эй\г
  • лет\г\п
  • хороший день

Как я могу это сделать? Есть ли готовые классы, которые я могу использовать?

-

Обновление:

Вот что я пытаюсь сделать и почему мне нужно сохранить символ конца строки (и почему символ EOL может отличаться).

Я читаю запрос POST. Они состоят из чистых текстовых сообщений, где строки всегда заканчиваются на \r\n (по стандартной спецификации). Однако запрос POST может содержать двоичные данные, которые могут содержать байты, которые похожи на символы завершения на объекты Java Reader.

В моем примере загружается изображение. Данные изображения отправляются по одной строке. Однако, однако, двоичные данные изображения содержат байты, которые READER будет интерпретировать как "\n", "\ r" или иногда "\ r\n", если эти два байта находятся рядом друг с другом.

Мне нужно прочитать запрос POST по одной строке за раз, потому что это работает. Полагаю, я МОЖЕТ прочитать все, а потом разобрать все. Но это не эффективно, особенно если загружен файл с большим файлом (скажем, 1024 MiB).

Ответ 1

Если вы хотите прочитать HTTP-запрос POST, я настоятельно рекомендую использовать BufferedInputStream.read() (not BufferedReader!) напрямую (без readLine -образных промежуточных абстракций), обращая внимание на все детали вручную, включая обработку CR и LF в соответствии с HTTP RFC.

Вот мой ответ на ваш более конкретный вопрос (как реализовать именно это readLine). Это может быть не самое быстрое решение, но сложность времени является оптимальной, и она работает:

import java.io.BufferedReader;
import java.io.IOException;   
public class LineReader {   
  private int i = -2;
  private BufferedReader br;
  public OriginalLineReader(BufferedReader br) { this.br = br; }
  public String readLine() throws IOException {
    if (i == -2) i = br.read();
    if (i < 0) return null;
    StringBuilder sb = new StringBuilder();
    sb.append((char)i);
    if (i != '\r' && i != '\n') {
      while (0 <= (i = br.read()) && i != '\r' && i != '\n') {
        sb.append((char)i);
      }
      if (i < 0) return sb.toString();
      sb.append((char)i);
    }
    if (i == '\r') {
      i = br.read();
      if (i != '\n') return sb.toString(); 
      sb.append((char)'\n');
    }
    i = -2;
    return sb.toString();
  }
}

Вы не найдете такой readLine, встроенный в Java. Вероятно, вы найдете аналогичный, но не совсем соответствующий readLine в стороннем файле .jar. Моя рекомендация - просто использовать вышеприведенную, если вам действительно нужна эта функция.