提问人:Cardinal System 提问时间:12/9/2022 最后编辑:Cardinal System 更新时间:12/9/2022 访问量:78
为什么 BufferedReader 和 Scanner 无法识别换行符?
Why are BufferedReader and Scanner not identifying line breaks?
问:
我有一个程序,它通过串行端口从外部测试仪器读取数据。它使用 jSerialComm 通过串行端口进行通信。数据是行分隔的,因此我决定使用 BufferedReader 逐行读取它。不幸的是,当调用 readLine()
方法时,它会阻塞,直到读取超时。我尝试使用 Scanner,但在 nextLine()
阻止方面遇到了同样的问题。
SerialPort port = SerialPort.getCommPort("COM4");
port.openPort();
port.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 10000, 0);
BufferedReader reader = new BufferedReader(new InputStreamReader(port.getInputStream()));
while(true) {
// This line blocks forever
System.out.println(reader.readLine());
}
我认为可能使用了一个特殊字符来换行,所以我从流中读取原始字节并将它们打印到控制台:
int byteRead;
InputStream stream = port.getInputStream();
while ((byteRead = stream.read()) != -1) {
System.out.write(byteRead);
System.out.print(byteRead);
}
以下是输出的示例:
10M77E69A65N78 32=61 32654957.46654654 32H72R82351048N78
13
10S83T84D68 32D68E69V86 32=61 32755.46553553 32H72R82351048N78
13
10L76O79W87E69S83T84 32=61 32250654.46351048 32H72R82351048N78
13
您可以清楚地看到 ASCII 字符 13(回车符)被用作行分隔符,在 Java 中表示为 。JavaDoc for BufferedReader#readLine
说:\r
读取一行文本。一条线被视为被任何人终止 换行符 ('\n')、回车符 ('\r') 或回车符 紧随其后的是换行符。
这让我非常困惑,因为 BufferedReader 应该在这种情况下工作,但不能。我为一个以行分隔的阅读器起草了一个概念验证,该阅读器在换行符(或 ASCII 10)和回车符 (ASCII 13) 上中断,并修剪前导和尾随以及字符:\n
\r
\r
\n
public class ScaleReader {
private InputStream scaleInputStream;
public ScaleReader(InputStream scaleInputStream) {
this.scaleInputStream = scaleInputStream;
}
public String readLine() throws IOException {
StringBuilder builder = new StringBuilder();
int charByte = scaleInputStream.read();
while (charByte != -1 && charByte == 13 || charByte == 10)
charByte = scaleInputStream.read();
if (charByte == -1)
return null;
builder.append((char) charByte);
while (true) {
charByte = scaleInputStream.read();
if (charByte == -1 || charByte == 13 || charByte == 10)
break;
builder.append((char) charByte);
}
return builder.length() == 0 ? null : builder.toString();
}
}
此代码按预期工作,并返回每次调用的正确数据。我不明白为什么 BufferedReader 在这种情况下不起作用,因为它显然应该将回车符识别为行终止符。readLine()
有解释吗?
答: 暂无答案
评论
InputStreamReader
BufferedReader
BufferedReader#read