当前位置: 首页 > news >正文

System.in 详解

System.in 详解

System.in 是 Java 提供的标准输入流InputStream 类型),默认关联键盘输入,通常用于从控制台读取用户输入。由于它是字节流(InputStream),直接使用较麻烦,一般会配合 Scanner 或 BufferedReader 进行字符读取。

1.标准输入流是用来接收用户在控制台上的输入的。(普通的输入流,是获得文件或网络中的数据)

2.标准输入流不需要关闭(它是一个系统级的全局的流,JVM负责最后的关闭)

3.也可以使用BufferedReader对标准输入流进行包装。这样可以方便的接收用户在控制台上的输入。(这种方式太麻烦了,因此JDK中提供了更好用的Scanner)

4.当然,你也可以修改输入流的方向(System.setIn())。让其指向文件。


1. 核心知识点

(1)System.in 的本质

  • 类型:InputStream(字节流,不是字符流)。

  • 默认行为:阻塞式读取(程序会等待用户输入)。

  • 使用场景:控制台输入、重定向输入(如 java Main < input.txt)。

(2)直接读取字节(原始方法)

java

try {int byteData = System.in.read();  // 读取1个字节(返回ASCII码)System.out.println("输入的内容:" + (char) byteData);
} catch (IOException e) {e.printStackTrace();
}
  • 缺点:只能读单个字节,中文会乱码(需用字符流处理)。


2. 常用封装方式

由于 System.in 是字节流,通常需要转换为字符流方便使用:

(1)配合 Scanner(最常用)

java

Scanner scanner = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = scanner.nextLine();  // 读取一行
System.out.println("你好," + name);
scanner.close();

优点

  • 支持按行、按单词、按数据类型(nextInt()nextDouble())读取。

  • 自动处理编码问题(默认使用系统字符集)。

(2)配合 BufferedReader(高效读取)

java

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入年龄:");
String ageStr = reader.readLine();  // 读取一行
int age = Integer.parseInt(ageStr);
System.out.println("年龄:" + age);
reader.close();

优点

  • 适合大文本输入(缓冲机制提升性能)。

  • 显式指定编码(如 UTF-8):

    java

    new InputStreamReader(System.in, StandardCharsets.UTF_8)

(3)对比 Scanner vs BufferedReader

特性ScannerBufferedReader
读取方式按行、单词、数据类型仅按行(readLine()
性能较慢(正则解析开销)更快(纯缓冲读取)
适用场景交互式输入(如控制台菜单)大文件或连续文本输入

3. 关键问题与解决方案

(1)中文乱码问题

  • 原因System.in 是字节流,默认使用系统编码(如 Windows 的 GBK),如果控制台编码不一致(如 IDEA 默认 UTF-8),会导致乱码。

  • 解决:强制指定编码:

    java

    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)
    );

(2)输入阻塞与超时

  • System.in.read() 会一直等待输入,若需超时控制,需用线程或 NIO(如 System.in.available() 检查是否有数据)。

(3)关闭问题

  • 不要关闭 System.in!否则后续代码无法再使用控制台输入。

  • 只需关闭封装流(如 Scanner 或 BufferedReader):

    java

    scanner.close();  // 会同时关闭底层 System.in(慎用!)
    // 推荐:仅关闭包装流
    BufferedReader reader = ...;
    reader.close();   // 不影响 System.in

4. 记忆技巧

(1)流程图:读取控制台输入

System.in (字节流)↓
InputStreamReader (字节→字符,可指定编码)↓
BufferedReader/Scanner (高效或灵活读取)

(2)口诀

"系统输入用 in
字节流转字符才顺,
Scanner 方便小输入,
BufferedReader 大文本稳!"


5. 面试常见问题

  1. System.in 是什么类型?它的缺点是什么?

    • 类型:InputStream(字节流)。

    • 缺点:直接使用需处理字节转换,不支持按行/数据类型读取。

  2. 如何避免 Scanner 关闭后导致 System.in 不可用?

    • 避免直接调用 scanner.close(),或改用 BufferedReader

  3. 如何用 System.in 读取中文?

    • 通过 InputStreamReader 指定编码(如 UTF-8)。


6. 实战应用

  • 控制台交互程序(如命令行工具):

    java

    Scanner scanner = new Scanner(System.in);
    while (true) {System.out.print("> ");String command = scanner.nextLine();if ("exit".equalsIgnoreCase(command)) break;System.out.println("执行命令:" + command);
    }
  • 重定向输入测试

    sh

    java Main < input.txt  # 从文件读取输入

总结

  • System.in 是 Java 标准输入流,需配合 Scanner 或 BufferedReader 使用。

  • 优先用 Scanner:简单交互(如读取数字、单词)。

  • 优先用 BufferedReader:高性能读取(如大文本或需要编码控制)。

  • 注意:不要关闭 System.in,避免编码乱码!

练习建议

  1. 写一个控制台计算器(读取用户输入的数字和运算符)。

  2. 比较 Scanner 和 BufferedReader 读取大文件的速度差异。

相关文章:

  • 个人自用-导入安装Hexo
  • Java 内存优化:如何避免内存泄漏?
  • React-useImperativeHandle (forwardRef)
  • CRT(阴极射线管)终端控制器
  • 手动实现LinkedList
  • 【算法数据结构】leetcode37 解数独
  • Unreal 从入门到精通之如何接入MQTT
  • 代码审计入门 原生态sql注入篇
  • 事件冒泡与捕获
  • LeetCode 438 找到字符串中所有字母异位词
  • C语言学习之预处理指令
  • 定制一款国密浏览器(9):SM4 对称加密算法
  • 微信小程序 时间戳与日期格式的转换
  • 今天分享一个网店客服回复数据集-用于网点客服AI助手自动回复智能体训练
  • 下采样(Downsampling)
  • python文件处理自用
  • 【PCIE配置空间】
  • 软件中的保护锁在工程项目中的应用
  • C算术运算符 printf输出格式 字符指针打印输出 使用scanf函数进行输入
  • MCGS昆仑通太屏笔记
  • “云南舞蹈大家跳”暨牟定“三月会”下周举行,城际公交免票
  • 老年人越“懒”越健康,特别是这5种“懒”
  • 瑞安房地产王颖:房地产市场看到很好的信号,上海项目销售压力不大
  • 左眼失明左耳失聪,办理残疾人证被拒?县残联:双眼残疾才能办
  • 女外交官杨扬出任中国驻圭亚那大使
  • 公安部道研中心:虚假宣传自动驾驶致严重后果,责任人或处2年以下刑期