Построитель процесса вызывает ошибку error2, которая не может найти указанный путь, даже если команда запускается из cmd

Я использую ProcessBuilder выполнить mysqldump из кода Java, и это мой код

    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

1 ответ

Решение

Во-первых, вы звоните 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);
}
Другие вопросы по тегам