Как получить доступ к пути к файлу с пробелами из командной строки в Java

Я пытаюсь запустить командный файл из программы Java. Например: у меня есть пакет "abc.bat" в папке "Program Files".

Я хочу выполнить этот пакет из моей Java-программы. Я использую класс CommandLine, Commons-exec jar.

CommandLine cmdLine = CommandLine.parse("cmd");
cmdLine.addArgument("/c start \"\" \"C:\\Program Files\\abc.bat\"");

DefaultExecutor exec = new DefaultExecutor();
Process p = Runtime.getRuntime().exec(cmdLine.toString());
exec.execute(cmdLine);

Приведенный выше код выдает ошибку "Windows не может найти файл. Убедитесь, что вы правильно ввели имя, и повторите попытку". И это из-за пробелов в пути.

Итак, я попробовал ответ, предоставленный здесь @brso05, и это работает. Но я хочу, чтобы это было в будущем классе. Пожалуйста, найдите мой код ниже и помогите мне исправить это.

final CommandLine cmdLine = CommandLine.parse("cmd.exe");
cmdLine.addArgument("/c");
cmdLine.addArgument("start");
cmdLine.addArgument("\""+ batchFileExecute.getParent().toString() + "\"");

ExecutorService es = Executors.newFixedThreadPool(1);
Future<?> future = es.submit(new Runnable() {
        public void run() {
                DefaultExecutor exec = new DefaultExecutor();
                        try {
                            Process p = Runtime.getRuntime().exec(cmdLine.toString());
                            exec.execute(cmdLine);
                            System.out.println(p.waitFor());
                            }
                        catch (IOException e) 
                            {
                                e.printStackTrace();
                            }
                        catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                        });
                            String thread_status = null;
                            try 
                            {
                                thread_status = future.get().toString(); 
                                System.out.println(thread_status+" completed the execution");
                            } 
                            catch (NullPointerException e) 
                            {
                            System.out.println("The execution of the received project is     complete.");                   
// In here I want to do some processing again.
}

Код, который я упомянул, работает, но он не работает, если в моем командном файле есть пробелы в пути. Можете ли вы помочь мне исправить это?

Потому что фрагмент, который вы дали работам, но потом я не могу поместить его в будущее. Это не работает в желаемой манере.

Заранее спасибо!

4 ответа

Это альтернативный способ:

     Runtime rt = Runtime.getRuntime();
     rt.exec("cmd.exe /c start \"\" \"C:\\Program Files\\abc.bat\"");

При использовании класса CommandLineaddArgumentметод без определения логического значения, он установитhandleQuotingдля вас, в основном добавляя кавычки к аргументу. Это метод, вызывающий:

          public CommandLine addArgument(String argument) {
        return this.addArgument(argument, true);
    }

    public CommandLine addArgument(String argument, boolean handleQuoting) {
        if (argument == null) {
            return this;
        } else {
            if (handleQuoting) {
                StringUtils.quoteArgument(argument);
            }

            this.arguments.add(new Argument(argument, handleQuoting));
            return this;
        }
    }

Изменение моего метода с:

              CommandLine cmd = new CommandLine("pdfinfo");
        cmd.addArgument("-box");
        cmd.addArgument(pdfFile.getAbsolutePath());

К:

              CommandLine cmd = new CommandLine("pdfinfo");
        cmd.addArgument("-box");
        cmd.addArgument(pdfFile.getAbsolutePath(), false); <-- change here

Решил проблему для меня. Кавычки не добавлялись, и CommandLine смогла найти файл.

У меня были те же имена файлов с пробелами при использовании ImageMagick. Вот код для решения проблемы:

String imageOutput = null;
ByteArrayOutputStream identifyStdout = new ByteArrayOutputStream();
ByteArrayOutputStream identifyStderr = new ByteArrayOutputStream();

try
{
    DefaultExecutor identifyExecutor = new DefaultExecutor();
    // End the process if it exceeds 60 seconds
    ExecuteWatchdog identifyWatchdog = new ExecuteWatchdog(60000);
    identifyExecutor.setWatchdog(identifyWatchdog);


    PumpStreamHandler identifyPsh = new PumpStreamHandler(identifyStdout, identifyStderr);
    identifyExecutor.setStreamHandler(identifyPsh);
    identifyExecutor.setExitValue(0); //0 is success

    CommandLine identifyCommandline = new CommandLine("identify");
    identifyCommandline.addArgument(destFile.getAbsolutePath(), false);

    DefaultExecuteResultHandler identifyResultHandler = new DefaultExecuteResultHandler();

    identifyExecutor.execute(identifyCommandline, identifyResultHandler);
    identifyResultHandler.waitFor();

    if (identifyResultHandler.getExitValue() != 0)
    {
        String output = identifyStdout.toString();
        _logger.debug("Standard Out = " + output);
        _logger.debug("Standard Err = " + identifyStderr.toString());

        String msg = "ImageMagick overlay encountered an error. ImageMagick returned a value of " + identifyResultHandler.getExitValue();
        throw new Exception(msg);
    }
    else
    {
        imageOutput = identifyStdout.toString();
        _logger.debug("Standard Out = " + imageOutput);
        identifyStdout.close();
        identifyStderr.close();
    }
}
catch(Exception e)
{
    _logger.debug("Error: " + e.getLocalizedMessage(), e);
}
finally
{
    identifyStdout.close();
    identifyStderr.close();
}

Важной частью здесь является:

identifyCommandline.addArgument(destFile.getAbsolutePath(), false);

Эта строка позволяет правильно обрабатывать путь к файлу с пробелами.

Вы пробовали с одинарными кавычками? По этому должно работать.

Другие вопросы по тегам