可以通过 System.setIn() 将标准输入流重定向为文件输入流,使 Scanner 等类自动从文件读取数据;需注意换行符处理、路径正确性、流关闭及单线程使用。

可以通过 System.setIn() 将标准输入流重定向为一个文件输入流,从而让原本读取控制台的代码(如 Scanner(System.in))自动从文本文件中读取数据,实现“模拟键盘输入”的效果。
核心原理:替换 System.in
System.in 默认是 InputStream 类型,指向键盘输入。Java 允许通过 System.setIn(InputStream) 动态替换它。只要传入一个基于文件的 FileInputStream,后续所有对 System.in 的读取操作(包括 Scanner、BufferedReader 等包装类)都会从该文件读取内容,就像用户一行行敲键盘一样。
基本实现步骤
以下是最简可行示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 准备一个文本文件(如
input.txt),每行代表一次“键盘输入”,例如:
hello
123
true - 在程序开头用
FileInputStream打开该文件,并调用System.setIn(...) - 之后创建
Scanner sc = new Scanner(System.in),它就自动从文件读了 - 记得在测试结束后恢复原始输入流(可选,但推荐用于单元测试或避免干扰)
完整示例代码
input.txt 内容:
立即学习“Java免费学习笔记(深入)”;
Alice25
Beijing
Java 代码:
import java.io.*;
import java.util.Scanner;
public class InputSimulator {
public static void main(String[] args) throws IOException {
// 保存原始 System.in,便于后续恢复
InputStream originalIn = System.in;
try (FileInputStream fis = new FileInputStream("input.txt")) {
System.setIn(fis); // 重定向标准输入
Scanner sc = new Scanner(System.in);
String name = sc.nextLine(); // 读 "Alice"
int age = sc.nextInt(); // 读 25
sc.nextLine(); // 消费换行符(nextInt 不读回车)
String city = sc.nextLine(); // 读 "Beijing"
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("City: " + city);
} finally {
// 可选:恢复原始输入,尤其在测试环境中很重要
System.setIn(originalIn);
}
}
}
注意事项与常见问题
-
换行符处理要小心:
nextInt()、nextDouble()等不消费行尾换行符,紧接着调用nextLine()会立刻返回空字符串。务必手动调用一次sc.nextLine()清除缓冲区 -
文件路径需正确:相对路径以项目工作目录(不是源码目录)为准;建议用绝对路径或
getClass().getResourceAsStream()加载资源文件 -
流关闭时机:
System.setIn()不会自动关闭原流或新流;应确保FileInputStream正确关闭(如用 try-with-resources) -
多线程不安全:
System.setIn()是 JVM 全局操作,不适合并发修改;单测中建议每次执行前重置

















