我一直在嘗試編寫一個java程序,它使用Runtime.getRuntime().exec()
方法來使用命令行來運行程序「tesseract」的一個實例。如何獲得java getRuntime()。exec()來運行帶參數的命令行程序?
一些背景,Tesseract是一個免費的開源程序,用於在圖片上執行OCR(光學字符識別)。它需要一個圖片文件並輸出一個文本文件。它是使用此命令的命令行程序(從命令提示外殼內)運行
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\""
,我最終有同樣的錯誤。
根據Using Quotes within getRuntime().exec我認爲問題在於我曾經試圖擺脫引號,所以這就是爲什麼我傳入一個字符串數組。但我仍然得到Exited with error code 1
。
是否可以使用java Runtime.getRuntime().exec()
命令執行命令行程序?
編輯:問題還是存在的
我曾嘗試不使用「CMD/C」在同一直線上的推理思維的葉夫根尼·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 /c
工作就像一個魅力。我想問題是Runtime.getRuntime().exec()
不能調用環境變量嗎?
我不知道,但問題可能會存在' C:\\ Program Files(x86)'在路徑中包含空格 –
我認爲這是問題的根源,這就是爲什麼我試圖使用引號,但如果那些不是我rk與exec,你有什麼建議可以做這項工作嗎? – Samuel
您正將一個數組傳遞給'rt.exec()'。不要在你的論點的開頭和結尾加上引號。這是關於如何將參數拆分的shell的信息,但是您已經完成了這些。 –