读取控制台输入(交互式命令行)
使用 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