读取控制台输入(交互式命令行)
使用 Scanner 或 BufferedReader 循环读取用户输入,根据命令执行操作:
import java.util.Scanner;
public class ConsoleInputExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入命令 (输入 'exit' 退出):");
while (true) {
System.out.print("> ");
String command = scanner.nextLine().trim(); // 读取整行
if ("exit".equalsIgnoreCase(command)) {
break;
} else if (!command.isEmpty()) {
executeCommand(command); // 执行自定义逻辑
}
}
scanner.close();
}
private static void executeCommand(String cmd) {
// 示例:根据输入执行不同操作
switch (cmd.toLowerCase()) {
case "help":
System.out.println("可用命令: help, version, calc");
break;
case "version":
System.out.println("程序版本 1.0");
break;
case "calc":
System.out.println("执行计算...");
break;
default:
System.out.println("未知命令: " + cmd);
}
}
}
执行外部系统命令(如调用Shell)
通过 ProcessBuilder 启动外部进程并连续输入命令:
import java.io.*;
public class ExternalCommandExample {
public static void main(String[] args) throws IOException {
// 1. 启动进程(以Linux Bash为例)
ProcessBuilder pb = new ProcessBuilder("/bin/bash");
pb.redirectErrorStream(true); // 合并错误流到输入流
Process process = pb.start();
// 2. 获取输入输出流
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
// 3. 连续输入命令
String[] commands = {"ls -l", "echo 'Hello Java'", "exit"}; // 需显式退出
for (String cmd : commands) {
writer.write(cmd + "\n"); // 写入命令
writer.flush(); // 立即发送
// 4. 读取输出
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("$")) break; // 根据提示符结束读取
System.out.println("输出: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
关键注意事项
-
避免死锁
- 同时读取输入流和错误流(使用
redirectErrorStream(true)合并流)。 - 为输出流添加
flush()确保命令被发送。
- 同时读取输入流和错误流(使用
-
资源释放
- 使用
try-with-resources自动关闭流。 - 显式终止进程:
process.destroy()。
- 使用
-
超时控制
防止进程阻塞:if (!process.waitFor(5, TimeUnit.SECONDS)) { process.destroyForcibly(); } -
安全性
- 避免直接执行用户输入的原始命令(防注入攻击)。
- 对输入进行白名单校验。
应用场景对比
| 场景 | 适用情况 | 工具 |
|---|---|---|
| 控制台交互 | 内部Java逻辑处理 | Scanner/BufferedReader |
| 调用系统命令 | 操作文件、网络等外部资源 | ProcessBuilder |
| 长时交互进程 | 与Python/Shell脚本持续通信 | Process + 多线程 |
常见问题解决
- 乱码问题:指定流编码
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)
- 命令无响应:启动子线程消费输出流(参考Oracle文档)。
- 权限不足:Java进程需具备执行目标命令的系统权限。
引用说明:本文代码遵循Java官方规范,关键方法参考自Oracle官方文档 ProcessBuilder 和 Scanner,安全建议依据OWASP输入验证标准。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7948.html