簡體   English   中英

如何讓java getRuntime()。exec()運行帶參數的命令行程序?

[英]How to get java getRuntime().exec() to run a command-line program with arguments?

我一直在嘗試編寫一個使用Runtime.getRuntime().exec()方法的java程序來使用命令行來運行程序“tesseract”的實例。

一些背景,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中的Using Quotes我認為問題是我曾試圖逃避引號,所以這就是我傳入String數組的原因。 但我仍然得到Exited with error code 1

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


編輯 :問題仍然存在

我試過不按照與Evgeniy Dorofeev和Nandkumar Tekale在下面提出的推理相同的思路使用“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.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
... 4 more

也許這會提供更多信息? 我真的很好奇是什么導致了這個問題。 無論我是否將轉義引用添加到我的參數中,問題都是一樣的。


編輯2 :一時興起,我提供了tesseract可執行文件的絕對路徑,而不是使用像魅力一樣工作的cmd /c 我想問題是Runtime.getRuntime().exec()不能調用環境變量嗎?

well tesseract是外部命令,因此您不需要將其與cmd一起使用。 tesseract添加到環境變量中。 使用直接命令:

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

存在狀態1表示功能不正確。 查看流程退出狀態

您沒有捕獲STDERR,因此當發生錯誤時,您不會從STDOUT(您正在捕獲它)中收到它們。 嘗試:

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

無需重新編譯和部署的另一種解決方法是使用舊的DOS樣式路徑,例如C:\\Program Files將是C:\\Progra~1 當然,只有在從配置文件或數據庫和注冊表等中讀取路徑時,這才有用。

另一個解決方法是提供文件的完整安裝路徑,如/usr/local/Cellar/tesseract/3.02.02/bin/tesseract“

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM