BufferedReader - 读取所有字符(不是行)
BufferedReader - read all characters (not lines)
如何使用 BufferedReader
将所有可用字符读取到 String
?
我有一个 Socket
,我想从中读取数据(如果可用)并将其存储在 String
中。问题是,我不能使用 readLine
,因为我收到的数据并不总是包含换行符或插入符 return,并且 readLine
会阻塞线程,直到它可以读取整行。如何使用 read
代替?
thread = new Thread(() ->
{
try {
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(true)
{
if (in.ready())
{
String someString = // ? read available data
delegate.didReadData(this, someString);
}
}
} catch (IOException e) {
delegate.didDropSocket(this);
}
});
thread.start();
编辑
1. 委托不关心字符串有多长,它只需要处理通过套接字到达的任何哈达 - 以及它的全部内容
2. 我不需要将数据切成块 - 我想阅读到达的所有内容
3. 是的,我有一个无限循环,因为我需要保持与套接字的连接并侦听数据,直到客户端断开连接 - 当我收到 IOException
时。我为套接字使用了一个单独的线程,因为会有更多的套接字需要监听。
BufferedReader#readLine(0)
treats '\n'、'\r' 和“\r\n”作为行分隔符。此行为无法更改,因此正如您所说,我们需要改用 read
的两个重载之一。
delegate
需要什么?它关心 someString
有多长吗?您需要 'chunk' 您从 in
读取的数据吗?您确定 String
合适吗?
我怀疑您需要 read(char[] cbuf, int off, int len) 方法。
假设您不需要一次读取一个字符,使用 read
,而不是使用一次一个字符的重载。
另外,你有一个无限循环。即使 ready
returns 为假,您的代码也不会终止,因为您永远不会离开 while(true)
循环。
或者这里的目的是让线程不断地检查更多数据,没有结束?我对 Java 标准库不够熟悉,无法提供详细信息,但我相信有比让线程 运行 一个内核处于 100% 负载更好的方法,检查额外的数据。简单的技巧是添加一个 sleep
调用,但我相信有更好的方法,可能涉及 Stream
class.
你需要始终明确指定你使用的是哪种编码,你不需要在阅读之前检查,当然你还必须跟踪你阅读了多少以及另一端是否已关闭连接。
省略了资源的异常处理和关闭。如有必要,可以增加缓冲区大小。否则这是一个非常惯用的读取循环。
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
char[] buf = new char[4096];
int size = 0;
while((size = in.read(buf)) != -1) {
String someString = new String(buf, 0, size);
delegate.didReadData(this, someString);
}
如何使用 BufferedReader
将所有可用字符读取到 String
?
我有一个 Socket
,我想从中读取数据(如果可用)并将其存储在 String
中。问题是,我不能使用 readLine
,因为我收到的数据并不总是包含换行符或插入符 return,并且 readLine
会阻塞线程,直到它可以读取整行。如何使用 read
代替?
thread = new Thread(() ->
{
try {
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(true)
{
if (in.ready())
{
String someString = // ? read available data
delegate.didReadData(this, someString);
}
}
} catch (IOException e) {
delegate.didDropSocket(this);
}
});
thread.start();
编辑
1. 委托不关心字符串有多长,它只需要处理通过套接字到达的任何哈达 - 以及它的全部内容
2. 我不需要将数据切成块 - 我想阅读到达的所有内容
3. 是的,我有一个无限循环,因为我需要保持与套接字的连接并侦听数据,直到客户端断开连接 - 当我收到 IOException
时。我为套接字使用了一个单独的线程,因为会有更多的套接字需要监听。
BufferedReader#readLine(0)
treats '\n'、'\r' 和“\r\n”作为行分隔符。此行为无法更改,因此正如您所说,我们需要改用 read
的两个重载之一。
delegate
需要什么?它关心 someString
有多长吗?您需要 'chunk' 您从 in
读取的数据吗?您确定 String
合适吗?
我怀疑您需要 read(char[] cbuf, int off, int len) 方法。
假设您不需要一次读取一个字符,使用 read
,而不是使用一次一个字符的重载。
另外,你有一个无限循环。即使 ready
returns 为假,您的代码也不会终止,因为您永远不会离开 while(true)
循环。
或者这里的目的是让线程不断地检查更多数据,没有结束?我对 Java 标准库不够熟悉,无法提供详细信息,但我相信有比让线程 运行 一个内核处于 100% 负载更好的方法,检查额外的数据。简单的技巧是添加一个 sleep
调用,但我相信有更好的方法,可能涉及 Stream
class.
你需要始终明确指定你使用的是哪种编码,你不需要在阅读之前检查,当然你还必须跟踪你阅读了多少以及另一端是否已关闭连接。
省略了资源的异常处理和关闭。如有必要,可以增加缓冲区大小。否则这是一个非常惯用的读取循环。
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
char[] buf = new char[4096];
int size = 0;
while((size = in.read(buf)) != -1) {
String someString = new String(buf, 0, size);
delegate.didReadData(this, someString);
}