как заставить java getruntime (). exec () запускать программу командной строки с аргументами?

<p>я пытался написать программу на java, которая использует метод <code>runtime.getruntime().exec()</code> для использования командной строки для запуска экземпляра программы "tesseract".</p><p>в некотором смысле, tesseract - это бесплатная программа с открытым исходным кодом, которая используется для оптического распознавания символов (ocr). он принимает в файл изображения и выводит текстовый документ. это программа командной строки, которая использует эту команду для запуска </p><p>(из командной строки командной строки)</p><pre><code>tesseract imagefilepath outfilepath [optional arguments] </code></pre><p>пример:</p><pre><code>tesseract "c:\program files (x86)\tesseract-ocr\doc\eurotext.tif" "c:\users\dreadnought\documents\testingfolder\out" </code></pre><p>первый аргумент вызывает программу tesseract, второй - абсолютный путь к файлу изображения, а последний аргумент - путь и имя того, каким должен быть выходной файл. для tesseract требуется только имя выходного файла, для которого не требуется расширение.</p><p>работая из командной строки, это работает отлично. однако я хотел запустить это из java-программы и столкнулся с некоторыми ошибками.</p><p>я нашел этот код очень полезным в качестве отправной точки</p><pre><code>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(); } } } </code></pre><p>распечатывает результат команды dir. однако, когда я изменил это так</p><pre><code>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(); } } } </code></pre><p>единственное, что он выводит - это <code>exited with error code 1</code>. это ожидаемый результат, если процесс завершился с ошибкой.</p><p>я даже попытался передать <code>"cmd /c tesseract \"c:\\program files (x86)\\tesseract-ocr\\doc\\eurotext.tif\" \"c:\\users\\dreadnought\\documents\\testingfolder\\eurotext-example\""</code>, и у меня возникла та же ошибка.</p><p>согласно <a href="https://stackoverflow.com/questions/161859/using-quotes-within-getruntime-exec">использование кавычек в getruntime (). exec</a> я думал, что проблема заключалась в том, что я пытался избежать кавычек, поэтому я передал массив string. но я все еще получаю <code>exited with error code 1</code>.</p><p>можно ли выполнить программу командной строки с помощью команды java <code>runtime.getruntime().exec()</code>?</p><hr><p><strong>edit</strong>: проблема все еще возникает</p><p>я пытался не использовать «cmd/c» мышление в соответствии с той же линией рассуждений, как предложили евгений дорофеев и нандкумар текале ниже. однако я получаю другую ошибку:</p><pre><code>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.<init>(unknown source) at java.lang.processimpl.start(unknown source) ... 4 more </code></pre><p>может быть, это дает больше информации? мне действительно любопытно, что вызывает эту проблему. также проблема в том, добавляю ли я к предыдущим цитатам аргументы.</p><hr><p><strong>edit 2</strong>: по какой-то причине я указал абсолютный путь к исполняемому файлу тессеракта и не использовал <code>cmd /c</code>, работающий как талисман. я думаю, вопрос в том, может ли <code>runtime.getruntime().exec()</code> не вызывать переменные окружения?</p>

<p>хорошо <code>tesseract</code> является внешней командой, поэтому вам не нужно использовать ее с <code>cmd</code>. добавьте <code>tesseract</code> к переменным окружения. используйте прямую команду как:</p><pre><code>string[] commands = {"tesseract", imagefilepath, outputfilepath }; </code></pre><p>существующий статус 1 означает неправильную функцию. смотрите <a href="http://pcsupport.about.com/od/fixtheproblem/tp/system\_error\_codes\_1\_99.htm">статус выхода из процесса</a> </p>

<p>вы не захватываете stderr, поэтому при возникновении ошибок вы не получаете их от stdout (который вы захватываете). пытаться:</p><pre><code>bufferedreader input = new bufferedreader(new inputstreamreader( pr.geterrorstream())); </code></pre>

<p>другой обходной путь без перекомпиляции и развертывания - использование старых путей в стиле dos, например, <code>c:\program files</code> будет <code>c:\progra~1</code>. конечно, это будет полезно, только если вы читаете пути из файла конфигурации или бд, реестра и т.д.</p>

<p>другой обходной путь - укажите полный путь установки файла, например /usr/local/cellar/tesseract/3.02.02/bin/tesseract "</p>