Java中System.in与FileDescriptor.in优劣对比及输入流效率问询
好问题!其实System.in本质上就是基于FileDescriptor.in封装出来的,咱们先拆解清楚两者的关系,再聊System.in的优势在哪里。
先搞懂底层关联
System.in是JVM启动时就自动初始化好的InputStream实例,它的底层就是绑定到FileDescriptor.in这个标准输入文件描述符的。你甚至可以通过System.in.getFD()方法拿到对应的FileDescriptor对象,本质上就是FileDescriptor.in。
System.in的核心优势
1. 开箱即用,代码更简洁
当你启动Java程序时,System.in已经配置完毕,直接拿来用就行:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
而如果用FileDescriptor.in,你得手动套一层FileInputStream,代码冗余不少:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(FileDescriptor.in)));
完全没必要多这一步——System.in已经帮你完成了FileInputStream的封装工作。
2. 支持输入重定向,灵活性拉满
System.in允许你通过System.setIn(InputStream)方法轻松切换输入源:
// 把输入从控制台改成读取文件 System.setIn(new FileInputStream("my-input.txt"));
但FileDescriptor.in是固定绑定到程序启动时的标准输入(通常是控制台)的,没法直接重定向。如果要换输入源,你还是得绕回System.in或者重新创建其他输入流。
3. 更贴合Java IO的设计习惯
Java的IO体系都是围绕InputStream/OutputStream构建的,System.in作为标准的InputStream实现,和BufferedReader、InputStreamReader等组件的适配性更好,代码更易读、符合通用编码规范。直接用FileDescriptor.in相当于跳过了标准封装层,代码显得不够“Java化”,其他开发者阅读时还要额外理解这部分逻辑。
补充:关于Scanner和BufferedReader的效率
你提到Scanner效率不如BufferedReader,这点完全正确。Scanner内部会做很多额外的解析工作(比如自动拆分基本类型、正则匹配),而BufferedReader只是单纯按字符/行读取,没有多余的解析开销,处理大量输入时速度优势明显。不过Scanner胜在易用性,比如可以直接读取int、double等类型,不用手动做字符串转换。
总结
除非你有特殊的底层操作需求,否则优先选择System.in就好——它更简洁、灵活,完全覆盖FileDescriptor.in的使用场景,还能省掉不少冗余代码。
内容的提问来源于stack exchange,提问作者Tanay Toshniwal

