2014-05-25 101 views
0

當我使用Runtime.getRuntime.exec()從Java運行命令時,我遇到了一個有趣的問題。我的代碼的以下部分基本上將doc文件轉換爲txt文件。 catdoc是一個將輸入文件轉換爲文本流並將其輸出到標準輸出的工具。輸出比重定向到一個txt文件。它對於某些文檔文件來說工作得很好,但是對於某些特定的文檔文件而言,它會掛起。Runtime.getRuntime.exec()掛起在不同情況下運行的相同命令

String[] strArr1 = new String[]{"catdoc", docFilePath}; 
Process p1= Runtime.getRuntime().exec(strArr1); 
p1.waitFor(); 

BufferedReader b = new BufferedReader(new InputStreamReader(p1.getInputStream())); 
FileWriter writeoutStream = new java.io.FileWriter(file.txt); 

while ((line = b.readLine()) != null) { 
    writeoutStream.write(line); 
    writeoutStream.write('\n'); 
} 
writeoutStream.close(); 
b.close(); 

我有許多文檔文件,這段代碼段在一些文件上工作,但它掛在其中一個文件上,並且沒有響應。我懷疑這可能是由文檔文件的大小造成的。那可能嗎?我想知道是否有什麼方法可以解決這個問題。

更新:我知道哪些文件導致運行時凍結。我嘗試在這些文件上使用catdoc命令,它會產生正確的結果。所以,輸入文件沒有錯。

+0

首先找到它掛起的文檔,並嘗試僅在該文檔上運行該命令以查找特定錯誤......無論如何,我的猜測是它在不存在的文檔中運行命令 – fmodos

+1

做到了。運行相同的命令並在終端中爲runtime.exec()掛起的文件生成期望的結果。我會更新我的問題。 – Lorderon

+0

'p1.getErrorStream()'檢查此InputStream中是否有任何錯誤 – fmodos

回答

0

如果在消耗所有輸出之前調用waitFor(),則進程可以阻止嘗試產生它。在讀取代碼後移動waitFor()。

+0

它沒有工作。仍然掛在同一個文件上。 – Lorderon

0

在黑暗中拍攝,但您是否嘗試過在-b標誌處運行catdoc命令?

-b - 進程損壞的MS-Word文件。通常,catdoc會檢查文件的前8個字節是否爲Microsoft OLE簽名。如果是這樣,它處理文件, ,否則它只是將其複製到標準輸入。它打算使用catdoc作爲 過濾器來查看擴展名爲.doc的所有文件。

+0

我不介意它與catdoc有關。我有同樣的問題將PDF文件轉換爲txt文件。正如我在我的問題中提到的,我認爲這與Runtime.getRuntime.exec()的內部有關。 – Lorderon

0

我已經嘗試了所有建議的解決方案在這裏和其他地方,但沒有幫助Runtime.exec()。看來,這是運行時命令中的內部緩衝區大小問題。我發現了runtime.exec()掛起的問題。這個問題在我剛剛學到的java文檔中有明確的描述。

「因爲一些本地平臺僅提供用於標準輸入和輸出流有限緩衝區的大小,沒有及時寫輸入流或讀出的子過程的輸出流可能會導致子阻塞,甚至死鎖。」

因此,我決定使用ProcessBuilder代替Runtime。它完全解決了我的問題。下面是我用我的問題代碼:

String[] strArr1 = new String[]{"catdoc", docFilePath}; 
ProcessBuilder probuilder = new ProcessBuilder(strArr1); 
Process process = probuilder.start(); 

InputStream is = process.getInputStream(); 
InputStreamReader isr = new InputStreamReader(is); 
BufferedReader br = new BufferedReader(isr); 

FileWriter writeoutStream = new java.io.FileWriter(file.txt); 

while ((line = br.readLine()) != null) { 
    writeoutStream.write(line); 
    writeoutStream.write('\n'); 
} 
writeoutStream.close(); 
br.close(); 
isr.close(); 
is.close(); 

//Wait to get exit value 
try { 
    int exitVal = process.waitFor(); 
    System.out.println("\n\nExit Value is " + exitVal); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

該代碼可以使用不同類型的命令(短期或長期)和不同大小的文件(或大或小)的完美的罰款。我的問題完全解決了。

相關問題