You need to enable JavaScript to run this app. Java如何模拟命令< file.txt输入重定向 适配mysql等命令调用场景
优惠活动
大模型
产品
解决方案
定价
更多

Java如何模拟命令< file.txt输入重定向 适配mysql等命令调用场景

解决方案

现有代码失效原因

  • 使用Scanner.nextLine()读取文件行时会自动丢弃行尾的换行符,仅调用stdin.write(line)不会写入换行,导致子进程收到的输入是无换行的连续内容,无法正常解析,这是核心问题。
  • 未消费子进程的标准输出和错误输出,可能导致子进程因为输出缓冲区满被阻塞,无法正常执行结束。

最简实现方案(Java 7及以上)

无需自行实现IO拷贝逻辑,ProcessBuilder已原生支持输入重定向,完全等效于命令行的< file.txt效果,适配你调用mysql的场景示例如下:

// 按参数拆分命令,避免空格等特殊字符导致的解析错误
ProcessBuilder pb = new ProcessBuilder("mysql", "-u", "你的用户名", "-p你的密码", "目标数据库名");
// 直接将source文件重定向为子进程的标准输入
pb.redirectInput(source);
// 可选:将子进程的输出、错误输出重定向到当前进程的对应流,避免缓冲区阻塞
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);

Process process = pb.start();
int ret = process.waitFor();

原有代码修复方案(兼容更早版本)

如果需要保留自行写流的逻辑,修复后代码如下:

String commandLine = "myCommand";
Process process = Runtime.getRuntime().exec(commandLine);

// 写入标准输入的线程
new Thread(() -> {
    try (BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
         Scanner scanner = new Scanner(source)
     ){
        String line;
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            stdin.write(line);
            stdin.newLine(); // 补充写入行尾换行符
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}).start();

// 消费子进程输出的线程,避免缓冲区阻塞
new Thread(() -> {
    try (InputStream stdout = process.getInputStream();
         InputStream stderr = process.getErrorStream()) {
        stdout.transferTo(System.out);
        stderr.transferTo(System.err);
    } catch (IOException e) {
        e.printStackTrace();
    }
}).start();

int ret = process.waitFor();

内容的提问来源于stack exchange,提问作者Fpasquer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 15:45:06