java - 进程生成器导致 error2 即使命令从 cmd 运行也找不到指定的路径

标签 java mysql processbuilder

我正在使用 ProcessBuilder 从 java 代码执行 mysqldump 这是我的代码

    public static void executeCommant(String... command) throws Exception {
        ProcessBuilder processBuilder = null;
        processBuilder = new ProcessBuilder(command);

        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();

        int resultCode = process.waitFor();

        if (resultCode != 0) {
            throw new Exception("" + readCommandOutput(process.getInputStream()));
        }
    }
private static String readCommandOutput(InputStream inputStream) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(inputStream));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line + System.getProperty("line.separator"));
            }
        } finally {
            br.close();
        }
        return sb.toString();
    }

public static void main(String[] args) throws Exception {

        executeCommant("mysqldump -u root -P 3316 -h localhost > G:\\test.sql");

    }

问题是我得到以下异常,即使当我从 cmd 运行相同的命令时我没有遇到任何问题,而且我只是想不通为什么它找不到指定的文件! PS:我尝试提供 mysqldump.exe 的完整路径并得到相同的结果

Exception in thread "main" java.io.IOException: Cannot run program "mysqldump -u root -P 3316 -h localhost > G:\test.sql": CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
    at com.etq.e2mc.platform.windows.WindowsProcess.executeCommant(WindowsProcess.java:46)
    at com.etq.e2mc.platform.windows.WindowsProcess.main(WindowsProcess.java:67)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:177)
    at java.lang.ProcessImpl.start(ProcessImpl.java:28)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
    ... 2 more

最佳答案

首先,您正在调用 ProcessBuilder(String... command)使用数组,这意味着数组的第一个值是程序。但是,您发送的是整个字符串 "mysqldump -u root -P 3316 -h localhost > G:\\test.sql",这不是程序。只有mysqldump是程序。

其次,当使用 getInputStream() 捕获输出时,您需要在 调用 waitFor() 之前执行此操作,否则您的输出有风险缓冲区已满,停止执行您正在运行的程序,本质上导致等待命令退出的程序与等待您读取输出的命令之间的死锁。如果您需要流,通常需要在单独的线程中读取它。

第三,您不能在命令字符串中使用 > 重定向输出。这是 cmd.exe 所做的事情,而您并没有调用 cmd.exe。由于您想重定向到一个文件,请直接使用 ProcessBuilder 执行此操作。

ProcessBuilder processBuilder = new ProcessBuilder(
        "mysqldump", "-u", "root", "-P", "3316", "-h", "localhost");
processBuilder.redirectErrorStream(true);
processBuilder.redirectOutput(new File("G:\\test.sql"));
Process process = processBuilder.start();
int resultCode = process.waitFor();
if (resultCode != 0) {
    throw new Exception("Program failed with error " + resultCode);
}

关于java - 进程生成器导致 error2 即使命令从 cmd 运行也找不到指定的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36981215/

相关文章:

缓存 java http 代理设置,直到 JVM 重新启动

java - 为什么 H2 不需要 JDBC 驱动程序

java - 导入根 CA 或中间 CA 而不是单个公共(public)证书

sql - 在单个结果行中连接选定的值,可以完成(不分组)吗?

mysql - SQL - 列总是对应的吗?

java - 如何使 JButton 在同一目录中运行可执行文件?

java - 使 Action 监听器(数组)更改值

mysql - 从大表中获取重复记录

java - 使用 ProcessBuilder 运行同一类的多个进程

Java ProcessBuilder 不写换行符