从 Java 中的输入流中读取一行文本,保留行终止字符

2022-09-04 23:16:53

我在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”,则每次迭代时都会遵循行变量:

  1. 你好
  2. 美好的一天

我想一次读取一行,但我想保留行终止字符:

  1. 你好\n
  2. 嘿\r
  3. yo\r\n
  4. 美好的一天

我该怎么做?有没有现成的类可以使用?

--

更新:

以下是我正在尝试执行的操作以及为什么我需要保留行尾字符(以及为什么 EOL 字符可能不同)。

我正在阅读 POST 请求。它们由纯文本消息组成,其中行始终以 \r\n 结尾(根据标准规范)。但是,POST 请求可能包含二进制数据,这些数据可能包含看起来像 Java Reader 对象的终止字符的字节。

在我的示例中,正在上传图像。图像数据在一行上发送。但是,图像的二进制数据包含字节,如果这两个字节恰好彼此相邻,READER 会将其解释为“\n”、“\r”或有时是“\r\n”。

我必须一次一行地阅读POST请求,因为这就是它的工作原理。我想,我可以阅读所有内容,然后解析整个内容。但这并不有效,特别是如果正在上传一个大文件(例如1024 MiB)文件。


答案 1

如果你想阅读HTTP POST请求,我强烈建议直接使用(不是!)(没有像中间抽象那样),手动注意所有细节,包括根据HTTP RFC处理CR和LF。BufferedInputStream.read()BufferedReaderreadLine

以下是我对您更具体问题的回答(如何准确实现它)。这可能不是最快的解决方案,但它的时间复杂度是最佳的,并且有效: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();
  }
}

你不会在Java中找到这样一个内置的。您可能会在第三方文件中找到类似但不完全匹配的 s。我的建议是,如果您真的需要该功能,请使用上面的那个。readLinereadLine.jar


答案 2

推荐