Почему мои пакетные файлы Windows не обрабатываются, когда Java выполняет их?

java windows batch-file cmd

471 просмотра

2 ответа

У меня есть 2 папки, каждая из которых содержит десятки командных файлов ( *.bat).

Пакетные файлы, содержащие текст, похожий на

del /f/q F:\MEDIA\IMAGE99\2010\270\z\4034\123.tif > nul
del /f/q F:\MEDIA\IMAGE99\2010\266\z\3025\456.tif > nul
del /f/q F:\MEDIA\IMAGE99\2010\267\z\3025\789.tif > nul
del /f/q F:\MEDIA\IMAGE99\2010\286\z\9025\101.tif > nul
del /f/q F:\MEDIA\IMAGE99\2010\272\z\6029\112.tif > nul
del /f/q F:\MEDIA\IMAGE99\2010\258\z\4034\134.tif > nul

или же

rmdir /q F:\MEDIA\IMAGE99\2010\270\z\4034
rmdir /q F:\MEDIA\IMAGE99\2010\266\z\3025
rmdir /q F:\MEDIA\IMAGE99\2010\267\z\3025
rmdir /q F:\MEDIA\IMAGE99\2010\286\z\9025
rmdir /q F:\MEDIA\IMAGE99\2010\272\z\6029
rmdir /q F:\MEDIA\IMAGE99\2010\258\z\4034

В Java я перечисляю каждый пакет Fileв каждой папке и циклически перебираю список, выполняя каждый пакетный файл следующим образом:

public static boolean batch(File file) {

    boolean handled = false;
    Process process = null;
    try {

        process = Runtime.getRuntime().exec("cmd /c start " + file);
        handled = process.waitFor() == 0;

    } catch (Exception ex) {
        // handling removed for example purposes
    } 

    return handled;
}

После возврата метода я удаляю командный файл.

Проблема заключается в том, что ни одна из команд в моих пакетных файлах не выполняется (файлы и папки, которые я запрашиваю, удалены или удалены нет), а процесс Java просто продолжается и удаляет сам пакетный файл.

Пакетные файлы находятся в папке d:\working\spaced folder\purge\batch_files\

Написав это, я подозреваю, что моя проблема в том, что я передаю путь к файлу с пробелом в exec()методе.

Правильно ли мое подозрение? Если так, как я могу решить это? Если нет, в чем может быть проблема?

Я собираюсь заглянуть в Java: выполните / cmd / c start path with with space \ program.exe теперь, когда я это рассмотрел.


ОБНОВИТЬ

Согласно комментариям ниже, я изменил свой код, но теперь вывод зависает, waitFor()и пакетный файл не обрабатывается (удаленные файлы, которые я запрашиваю, все еще там).

Код:

        String commandString = "cmd /c \"" + file +"\"";
        logger.info("COMMAND " + commandString);
        process = Runtime.getRuntime().exec(commandString);
        logger.info("WAITING FOR " + commandString);
        handled = process.waitFor() == 0;
        logger.info("HANDLED " + commandString + " = " + handled);

Выход:

COMMAND : cmd /c "d:\working\spaced folder\purge\deleteBatch\F_140.bat"
WAITING FOR : cmd /c "d:\working\spaced folder\purge\deleteBatch\F_140.bat"
Автор: JoshDM Источник Размещён: 12.11.2019 09:49

Ответы (2)


3 плюса

Решение

теперь вывод висит на waitFor()

Когда вы запускаете внешний процесс из Java с использованием, Runtime.execвы должны прочитать любой вывод, который производит процесс, в противном случае процесс может блокироваться ( источник: JavaDocs для java.lang.Process ).

Используйте ProcessBuilderвместо этого и вызовите redirectErrorStreamдля объединения стандартного потока вывода и ошибок, затем прочитайте весь контент, process.getInputStream()пока не достигнете EOF. Только тогда безопасно звонить waitFor.

ProcessBuilder также поможет с проблемой пробелов, так как вы должны разбить командную строку на отдельные слова самостоятельно

ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath());
Автор: Ian Roberts Размещён: 27.01.2014 10:51

0 плюса

Используется код успешного решения, основанный на ответе Яна Робертса:

Использует Apache Commons-IO

package com.stackoverflow.windows;

import java.io.File;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;

public class Command {

    private Command() {}

    public static boolean batch(File file) {

        boolean handled = false;
        Process process = null;
        ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath());
        pb.redirectErrorStream(true);

        try {

            process = pb.start();
            IOUtils.copy(process.getInputStream(), new NullOutputStream());
            handled = process.waitFor() == 0;

        } catch (Exception ignore) {

            // Only throws an IOException we're trying to avoid anyway, 
            // and an expected InterruptedException 
            // handled will be false

        } finally {

            if (process != null) {

                IOUtils.closeQuietly(process.getInputStream());
            }           
        }

        return handled;
    }
}
Автор: JoshDM Размещён: 27.01.2014 11:22
Вопросы из категории :
32x32