2011-05-02 64 views
5

我想一堆文件具有特定擴展名從一個文件夾使用copy命令複製到另一個使用CMD,繼承人笏即時通訊做拷貝文件,問題在Java

String[] command = new String[3]; 
command[0] = "cmd"; 
command[1] = "/c"; 
command[2] = "copy C:\\output\\html\\*.txt C:\\output\\"; 

ProcessBuilder copyFiles = new ProcessBuilder(command); 
p = copyFiles.start(); 
p.waitFor(); 

事情是,這段代碼適用於小於5左右的文件,但只是停止響應文件數量更多(甚至15個文件)!並且文件也不被複制! 我不知道問題是什麼,如果有人能幫忙,會很高興! :)

+1

是否從命令窗口運行該命令並且該目錄中有超過15個txt文件會導致它停止響應?或者這是否僅在從JVM調用該命令時發生? – keepitreall89 2011-05-02 16:42:11

+0

@ keepitreall89,從命令窗口工作正常!只有從jvm它提供probs .. – 2011-05-02 16:45:57

+1

一個可能的解決方案是在「C:\\ output \\」之後在您的命令[2]字符串中添加/ Y標誌,這將防止它試圖詢問您是否想要覆蓋具有相同名稱的文件。問題可能在於具有該名稱的文件已經存在,因此如果您想覆蓋它,只有您的java調用不會「監聽」該文件。 – keepitreall89 2011-05-02 16:46:02

回答

6

您沒有讀取輸出copy命令正在生成。

使用ProcessBuilder產生子進程時,子進程生成的輸出會寫入緩衝區。如果這個緩衝區沒有被讀取,它最終會填滿。當它填滿時,copy命令無法再寫入,因此被操作系統阻止。然後它被迫等待,直到讀取緩衝區中的空間。

我用20個文件運行你的代碼,我發現它確實掛起。

解決您的問題的一種方法是將輸出從copy重定向到NULcopy的大部分輸出都是它複製的所有文件的列表,您可能不會太在意。要做到這一點重定向,修改分配給command[2]線以下:

command[2] = "copy C:\\output\\html\\*.txt C:\\output\\ >NUL 2>NUL"; 

但是,如果有複製文件的問題,你可能不知道,如果你做到這一點。

或者,您可以讀取copy命令生成的輸出。下面的代碼發送到System.out,但你可以很容易地在其他地方發送或完全忽略它,如果你想:

String[] command = { "cmd", "/c", "copy C:\\output\\html\\*.txt C:\\output\\" }; 
ProcessBuilder copyFiles = new ProcessBuilder(command); 
copyFiles.redirectErrorStream(true); 
p = copyFiles.start(); 

// The InputStream we get from the Process reads from the standard output 
// of the process (and also the standard error, by virtue of the line 
// copyFiles.redirectErrorStream(true)). 
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
String line; 
do { 
    line = reader.readLine(); 
    if (line != null) { System.out.println(line); } 
} while (line != null); 
reader.close(); 

p.waitFor(); 

我給每個接近一個快速測試使用相同的20個文件,並沒有辦法掛。

編輯:您可能也想嘗試一個「混合」的辦法,由扔掉什麼copy寫到標準輸出(例如文件,它是複製的列表),但使用第二種方法來讀取它寫入標準錯誤(例如錯誤消息)。爲此,您需要添加>NUL,它將copy的標準輸出重定向到NUL,但您不會添加2>NUL,因爲它會將標準錯誤重定向到NUL

+0

woodward,非常感謝,我接受這個答案,我實際上正在嘗試這個緩衝區讀者方法,我理解了第二種方法,但在第一種情況下,它爲什麼重定向兩次?有什麼意義? :) – 2011-05-02 18:01:09

+0

伍德沃德,我的意思是爲什麼它> NUL和2> NUL? – 2011-05-02 18:20:04

+1

@Hari:所有進程都有標準輸出和用於寫入的標準錯誤流,請參閱http://en.wikipedia.org/wiki/Standard_streams。使用'> NUL'和'2> NUL'將標準輸出和標準錯誤流重定向到'NUL'。你不能將它們重定向到一起。當然,如果'copy'寫很多標準的錯誤流,並且你沒有從它的標準錯誤中讀取,它會掛起。 – 2011-05-02 20:56:16