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);
}