从Java中的输入流中读取一行文本,保留行终止字符 [英] Read a line of text from an input stream in Java keeping the line-termination character(s)

查看:181
本文介绍了从Java中的输入流中读取一行文本,保留行终止字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中有这个代码:

I have this code in Java:

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

如果输入流包含以下内容:hello \\\
hey \\\\\\ =今天,那么每个行变量都会跟随迭代:

If the input stream contains the following: "hello\nhey\ryo\r\ngood-day", then line variable would be following on each iteration:


  1. 你好

  2. hey

  3. yo

  4. good-day

  1. hello
  2. hey
  3. yo
  4. good-day

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

I want to read one line at a time, but I want to keep the line-termination character(s):


  1. hello \ n

  2. hey \ r

  3. yo \\ n

  4. 美好的一天

  1. hello\n
  2. hey\r
  3. yo\r\n
  4. good-day

我该怎么做?我可以使用现成的课程吗?

How can I do this? Is there a ready-made classes I can use?

-

更新:

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

Here's what I'm trying to do and why I need to keep the end-of-line character (and why the EOL character may be different).

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

I'm reading a POST request. They consists of pure text messages where the lines always end with \r\n (by the standard specification). However POST request may contain binary data, which may contain bytes that look like termination characters to Java Reader objects.

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

In my example, an image is being uploaded. The image data is sent on a single line. However, however the image's binary data contains bytes that the READER would interpret as "\n", "\r" or sometimes "\r\n" if those two bytes happens to be next to each other.

我必须一次读取一行的POST请求,因为它是如何工作的。我想,我可以阅读所有内容然后解析整个事情。但这并不高效,特别是如果要上传大文件(比如1024 MiB)文件。

I have to read the POST request one line at a time because that's how it works. I suppose, I COULD read everything and then parse the whole thing. But that's not efficient, especially if a large file (say 1024 MiB) file is being uploaded.

推荐答案

如果你想阅读一个HTTP POST请求,我强烈建议直接使用 BufferedInputStream.read()(不是 BufferedReader !)(不含 readLine -like intermediate abstractions),手动注意所有细节,包括根据HTTP RFC处理CR和LF。

If you want to read a HTTP POST request, I strongly suggest using BufferedInputStream.read() (not BufferedReader!) directly (without readLine-like intermediate abstractions), paying attention to all details manually, including the handling of CR and LF according to the HTTP RFC.

以下是我对更具体问题的回答(如何正确实现 readLine )。这可能不是最快的解决方案,但它的时间复杂度是最佳的,并且它可以工作:

Here is my answer to your more specific question (how to implement exactly that readLine). This might not be the fastest solution, but it's time complexity is optimal, and it works:

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中。您可能会在第三方 .jar 文件中找到类似但不完全匹配的 readLine 。如果你确实需要这个功能,我建议只使用上面的那个。

You won't find such a readLine built into Java. It's likely that you will find similar, but not exactly matching readLines in a third-party .jar file. My recommendation is just to use the one above, if you really need that feature.

这篇关于从Java中的输入流中读取一行文本,保留行终止字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆