如何让java getRuntime().exec()运行带有参数的命令行程序?

2022-09-03 02:48:25

我一直在尝试编写一个java程序,该程序使用该方法使用命令行来运行程序“tesseract”的实例。Runtime.getRuntime().exec()

一些背景,Tesseract是一个免费的开源程序,用于对图片执行OCR(光学字符识别)。它接收图片文件并输出文本文档。它是一个命令行程序,使用此命令运行

(从命令提示符 shell 中)

tesseract imageFilePath outFilePath [optional arguments] 

例:

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

第一个参数调用 tesseract 程序,第二个参数是图像文件的绝对路径,最后一个参数是输出文件应包含的路径和名称。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中使用引号,我认为问题在于我试图转义引号,所以这就是为什么我传入了一个字符串数组。但我仍然得到.Exited with error code 1

是否可以使用 java 命令执行命令行程序?Runtime.getRuntime().exec()


编辑:问题仍然存在

我尽量不使用“cmd / c”思维,就像Evgeniy Dorofeev和Nandkumar Tekale在下面建议的那样。但是,我得到一种不同的错误:

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

也许这提供了更多信息?我真的很好奇是什么导致了这个问题。同样,无论我是否将转义引号添加到我的论点中,问题都是一样的。


编辑2:一时兴起,我提供了一个绝对的路径到tesseract可执行文件,而不是像吊饰一样使用工作。我想问题是不能调用环境变量?cmd /cRuntime.getRuntime().exec()


答案 1

您没有捕获 STDERR,因此当发生错误时,您不会从 STDOUT(您正在捕获)接收它们。尝试:

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

答案 2

well 是外部命令,因此您不需要将其与 .添加到环境变量。使用直接命令作为:tesseractcmdtesseract

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

存在状态 1 表示功能不正确。查看进程退出状态


推荐