如何通过Reader.ready方法非阻塞地判定字符流变量是否可读实战

秋涛同学_6722

秋涛同学_6722

2026-05-22

225人浏览

原创

reader.ready() 不能可靠判断字符流是否可读,仅表示缓冲区是否有数据可立即读取;误用会导致跳过数据或卡死,应改用 readline() 循环或 nio 非阻塞方案。

如何通过reader.ready方法非阻塞地判定字符流变量是否可读实战

Reader.ready() 方法本身不能可靠判断“字符流是否可读”,尤其在网络或管道类流中。它只表示“当前缓冲区是否有数据可立即读取”,不是“后续会不会有数据”或“流是否已就绪”。误用 ready() 做循环条件(如 while(reader.ready()))极易导致跳过数据、空读、甚至逻辑卡死。

ready() 的真实含义和限制

ready() 是一个非阻塞查询方法,返回 true 仅说明:内部缓冲区中已有至少一个字符可被 read() 或 readLine() 立即取走,无需等待。

  • 对 FileReader、StringReader 等本地资源流,ready() 大多返回 true(除非刚打开且未填充缓冲区)
  • 对 InputStreamReader 包装的网络 Socket 流,ready() 往往返回 false —— 即使服务器已发数据,但因 TCP 接收窗口、Nagle 算法或应用层未及时填充 BufferedReader 缓冲区,JVM 无法保证“此刻有字符在缓冲区”
  • readLine() 返回 null 只代表流已关闭且缓冲区彻底耗尽(EOF),不等于“没数据可读”;而 ready() 返回 false 也不等于“流断开”或“永远没数据”

常见误用及后果

以下写法是典型陷阱:

while (reader.ready()) {  // ❌ 错误:可能一次都不进循环,即使后续有大量数据
    String line = reader.readLine();  // 也可能返回 null(缓冲区空但连接未关)
}
  • 若首次调用 ready() 就是 false,整个循环跳过,丢失所有后续到达的数据
  • 若 readLine() 在中间某次返回 null(比如对方主动 close 输出流),但连接仍通,后续数据可能再也无法触发 ready() 为 true
  • ready() 和 readLine() 混合使用顺序不当,容易造成状态错乱(例如先 readLine() 耗尽缓冲区,再查 ready() 得 false,却误判为“无数据”)

真正可用的非阻塞读取策略

要实现“不阻塞主线程、又能及时响应新数据”,应放弃依赖 ready() 做主控,改用以下方式:

  • 用带超时的轮询 + try-catch 捕获阻塞:对 BufferedReader,可配合线程 sleep + readLine() 调用,并捕获 IOException 判断连接状态
  • 改用 NIO 的 Selector + CharsetDecoder:用 java.nio.channels.SocketChannel 配合非阻塞模式,通过 select() 获取就绪通道,再 decode 字符,这才是真正的非阻塞字符流处理
  • 用 Scanner 配合 hasNextLine()(注意:它底层仍可能阻塞):仅适用于可控场景(如本地文件或调试模拟),不推荐用于生产网络流
  • 明确约定结束标记:让对端发送特定行(如 "END"),客户端持续 readLine() 直到匹配该标记,不依赖 ready() 或 EOF

简单安全的替代写法(适用于短连接或测试)

如果只是想避免无限阻塞,又不想引入 NIO,可这样写:

String line;
while ((line = reader.readLine()) != null) {
    if (line.trim().isEmpty()) continue;  // 忽略空行
    process(line);
}
// 此时 reader 已到末尾或连接关闭

这个模式靠 readLine() 自身阻塞等待有效数据,不拼凑 ready(),逻辑清晰、不易出错。如需中断等待,应配合线程 interrupt 或使用支持 cancel 的异步 API(如 CompletableFuture + BufferedReader.lines())。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10457

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7582

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6632

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1144

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

928

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1376

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2749

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20071

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1215

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习