Вопрос по exec, process, java, runtime.exec – Как получить Java getRuntime (). Exec () для запуска программы командной строки с аргументами?

9

Я пытался написать программу Java, которая используетRuntime.getRuntime().exec() метод использования командной строки для запуска экземпляра программы "тессеракт».

В некотором смысле, Tesseract - это бесплатная программа с открытым исходным кодом, которая используется для оптического распознавания символов на изображениях. Он принимает в файл изображения и выводит текстовый документ. Это программа командной строки, которая использует эту команду для запуска

(из оболочки командной строки)

tesseract imageFilePath outFilePath [optional arguments] 

пример:

tesseract "C:\Program Files (x86)\Tesseract-OCR\doc\eurotext.tif" "C:\Users\Dreadnought\Documents\TestingFolder\out"

первый аргумент вызывает программу tesseract, второй - абсолютный путь к файлу изображения, а последний аргумент - путь и имя того, каким должен быть выходной файл. Тессеракт требует только имя выходного файла, расширение которого не требуется.

Работая из командной строки, это работает отлично. Тем не менее, я хотел запустить это из Java-программы и столкнулся с некоторыми ошибками.

Я нашел этот код очень полезным в качестве отправной точки

public class Main
{
   public static void main(String args[])
   {
      try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c dir";

         System.out.println(cmdString);
         Process pr = rt.exec(cmdString);

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
         }

         int exitVal = pr.waitFor();
         System.out.println("Exited with error code " + exitVal);

      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
   }
}

Распечатывает результат команды dir. Однако, когда я изменил это так

public class Main
{
   public static void main(String args[])
   {
      try
      {
         Runtime rt = Runtime.getRuntime();
         String imageFilePath = "\"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\"";
         String outputFilePath = "\"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\"";
         String[] commands = {"cmd", "/c", "tesseract", imageFilePath, outputFilePath };

         Process pr = rt.exec(commands);

         BufferedReader input = new BufferedReader(new InputStreamReader(
               pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
         }

         int exitVal = pr.waitFor();
         System.out.println("Exited with error code " + exitVal);
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
   }
}

Единственное, что он выводит, этоExited with error code 1, Это ожидаемый результат, если процесс завершился с ошибкой.

Я даже пытался пройти"cmd /c tesseract \"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\" \"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\"" и я в конечном итоге с той же ошибкой.

В соответствии сИспользование кавычек в getRuntime (). Exec Я думал, что проблема заключалась в том, что я пытался избежать кавычек, поэтому я передал массив String. Но я все еще получаю.Exited with error code 1

Можно ли выполнить программу командной строки с JavaRuntime.getRuntime().exec() команда?

РЕДАКТИРОВАТЬ: Проблема все еще возникает

Я пытался не использовать "cmd / c " размышляя по тому же принципу, что и Евгений Дорофеев и Нандкумар Текале, предложенные ниже. Однако я получаю другую ошибку:

java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system cannot find the file specified
java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system  cannot find the file specified
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at Main.main(Main.java:15)
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.(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
... 4 more

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

РЕДАКТИРОВАТЬ 2: По какой-то причине я указал абсолютный путь к исполняемому файлу tesseract и не использовалcmd /c работал как шарм. Я думаю, что вопрос можетRuntime.getRuntime().exec() не вызывать переменные среды?

Я подумал, что это корень проблемы, поэтому я пытался использовать цитаты, но если они неt работать с exec, у вас есть предложение, как я мог бы сделать эту работу? Samuel
@ Сэмюэль Подумайте о том, чтобы пометить этот вопрос как ответ, и задайте свой следующий вопрос оRuntime.exec и переменные среды отдельно. that other guy
да я использовал без cmd / c Samuel
Вы'передаем массив вrt.exec(), Дон»ставьте кавычки в начале и в конце ваших аргументов. Это информация для оболочки о том, как разделить аргументы, но вымы уже сделали это. Niklas R

Ваш Ответ

4   ответа
0

Другой обходной путь - указать полный путь установки файла, например /usr/local/Cellar/tesseract/3.02.02/bin/tesseract "

0

Вы не фиксируете STDERR, поэтому при возникновении ошибок вы не получаете их от STDOUT (который вы фиксируете). Пытаться:

BufferedReader input = new BufferedReader(new InputStreamReader(
               pr.getErrorStream()));
0

Другой обходной путь без перекомпиляции и развертывания - использование старых путей в стиле DOS, например, дляC:\Program Files было быC:\Progra~1, Конечно, это будет полезно, только если вы читаете пути из файла конфигурации или БД, реестра и т. Д.

1

Что жtesseract является внешней командой, поэтому вам не нужно использовать ее сcmd, добавлятьtesseract к переменным среды. Используйте прямую команду как:

String[] commands = {"tesseract", imageFilePath, outputFilePath };

Существующий статус 1 означает неправильную функцию. Увидетьстатус выхода из процесса

Вы проверили его запуск в командной строке? Nandkumar Tekale
да, он отлично работает из командной строки Samuel
Тессеракт уже находится в переменных окружения. Samuel

Похожие вопросы