如何使用 BufferedReader 读取 CR LF 行?

How to read CR LF line with BufferedReader?

我正在尝试创建一个简单的 java 服务器应用程序,但我很难使用 BufferedReader 正确读取用户的输入。 问题是行分隔符只是 CR LF ("\r\n") - 所以我不能使用 readLine() 标准方法。因此,我尝试实现自己的方法:

private String readCRLFLine(BufferedReader in) {

    StringBuilder result = new StringBuilder();
    char cr = 'a'; // initialize cr
    char lf;

    try {
        while (((lf = (char) in.read()) != '\n') && (cr != '\r')) {
            cr = lf;
            result.append(lf);
        }
        result.deleteCharAt(result.length() - 1); // delete \r from the result
    } catch (IOException ex) {
        // handle the exception here
    }

    return result.toString();
}

现在,当我尝试获取并打印结果时:

while ((userMessage = readCRLFLine(inputStream)) != null) {
        System.out.println(userMessage);
        break;
}

...它仅将字符序列打印到第一个换行符(“\r”或“\n”),其余输入由方法的第二次调用读取 readCRLFLine(inputStream) - 应该已经读取了其他输入。

我希望能够处理如下输入:

"abc\rabc\n\r\abc\r\n"

在这种情况下,userMessage 应该是:

"abc\rabc\n\r\abc"

我不能使用扫描仪,它是 "useDelimeter("\r\n")" 方法,因为我需要使用 "clientSocket.setSoTimeout(TIMEOUT)" 设置超时,据我所知,这不是可以使用扫描仪。

我的 "readCRLFLine" 方法有什么问题?这个问题还有其他解决方案吗?

如有任何帮助,我们将不胜感激。

您的方法不正确,因为 while 条件不是您实际需要的。

它说 "As long as the currently read character is different than \n and the previous character is different than \r, continue reading"。

但这意味着当您读取 \n 时,该条件为 false,因为 lf != '\n' 为 false。所以它会在第一个 \n 处停止。它还将在 \r 之后的任何字符处停止,因为 cr != '\r' 将成为 false,从而使组合条件为假。

你想在当前字符为 \n 且前一个字符为 \r 时停止循环。这意味着你的 while 条件应该是 ! ( lf == '\n' && cr == '\r').

现在注意德摩根定律:"not (A and B)" 等价于 "not A OR not B"。您错误地决定使用 AND 而不是 OR。将您的条件更改为:

while (((lf = (char) in.read()) != '\n') || (cr != '\r')) {
   ...
}

顺便说一句,在将它转换为 char 并进行比较之前,您可能应该检查从 in 读取的值是否不是负值。负值表示客户端关闭了连接,如果发生这种情况,您将陷入无限循环。