You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BufferedReader读取InputStream时如何跳出while读取死循环

问题原因

BufferedReader.readLine() 返回null的唯一前提是绑定的输入流已经到达末尾,没有可读取内容且流已关闭。在Socket场景下循环无法退出,本质是数据发送端发完JSON内容后,没有关闭输出流或者给出传输结束信号,readLine() 读完当前已收到的JSON数据后,会一直阻塞等待对端发送新数据,永远拿不到null返回值,自然无法跳出循环。
你当前的代码逻辑是默认读取到流彻底关闭才停止,和「单次读取一段JSON就完成本次接收」的需求不匹配。

解决方案

根据你的场景选以下任意一种方案即可:

  • 约定传输结束标记
    收发双方提前约定一个不会和JSON正文冲突的结束标识,比如单独一行传EOF,发送端发完完整JSON后额外发一行这个标识,接收端读到标识就主动跳出循环。
    参考代码:
    String line;
    StringBuilder sb = new StringBuilder();
    while ((line = br.readLine()) != null) {
        if ("EOF".equals(line)) {
            break;
        }
        sb.append(line);
    }
    
  • 前置传输数据长度
    发送端在发JSON正文前,先把JSON字符串的总长度发过来,接收端按照长度读取对应字节数后就停止读取,这是网络传输场景的通用标准方案,不会出现标识和正文冲突的问题。
  • 发送端主动关闭输出流
    如果是单次传输场景,发送端写完JSON内容后,调用shutdownOutput()关闭自身的输出流(不要直接关闭整个Socket,避免数据未发送完成就断连),接收端读完所有数据后readLine()就会返回null,循环正常退出。
  • 设置Socket读取超时
    给Socket设置超时参数:socket.setSoTimeout(3000),单位是毫秒,当连续3秒没有读到新数据时会抛出SocketTimeoutException,捕获异常后跳出循环即可。这种方案适合无法修改发送端逻辑的场景,注意超时时间要结合实际网络情况调整,避免正常传输过程中误触发超时。

注意:如果传输的是带换行的格式化JSON,readLine()会自动丢弃每行末尾的换行符,拼接后的字符串会丢失原有换行,如果JSON组件对格式校验严格,append的时候需要手动补上\n。

内容的提问来源于stack exchange,提问作者Yondela Sasayi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:24:18