2015-06-11 45 views
2

下載程序(的NirCmd)像這樣經過後,通過流程運行程序不能下載它(JAVA)

Process process = Runtime.getRuntime().exec("nircmd.exe speak text Hi"); 

但它拋出這個例外:

java.io.IOException: Cannot run program "nircmd.exe": CreateProcess error=32, The process cannot access the file because it is being used by another process 
at java.lang.ProcessBuilder.start(Unknown Source) 
at java.lang.Runtime.exec(Unknown Source) 
at java.lang.Runtime.exec(Unknown Source) 
at java.lang.Runtime.exec(Unknown Source) 
at Main.main(Main.java:18) 

Caused by: java.io.IOException: CreateProcess error=32, The process cannot access the file because it is being used by another process 
at java.lang.ProcessImpl.create(Native Method) 
at java.lang.ProcessImpl.<init>(Unknown Source) 
at java.lang.ProcessImpl.start(Unknown Source) 
... 5 more 

回答

-2

固定!以下是我做的:

當它跑:

URL website = new URL(
      "https://copy.com/Q4qch6FBPZkrclxG/nircmd.exe?download=1"); 
    ReadableByteChannel rbc = Channels.newChannel(website.openStream()); 
    FileOutputStream fos = new FileOutputStream("nircmd.exe"); 

    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 

它需要:

if(new File("nircmd.exe").exists()) { 
    ... code here 
} 
+1

這不能解決問題。它只隱藏它。 – user2864740

4

關閉的OutputStream。否則(至少在Windows中)它會在底層文件資源上保留一段獨佔的寫鎖,以保留一些不確定的持續時間。

應該通過以確定性方式呼叫close來處理以避免這個問題。

如果close稱爲「在將來,當/如果終結器運行或程序退出一些不確定的時間被關閉」,那麼流將。如所看到的,這種非確定性行爲可能導致錯誤和不穩定的行爲。

爲了使生活更輕鬆,因爲它是非常繁瑣的正確包裝並調用close方法,一個try-with-resources語句可用於:

try (
    ReadableByteChannel rbc = Channels.newChannel(website.openStream()); 
    FileOutputStream fos = new FileOutputStream("nircmd.exe")) 
) { 
    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 
} 

// Now nircmd.exe can be opened because fos.close() 
// is GUARANTEED to have been called (by try-with-resources) 
// and the underlying file is no longer [exclusively] opened. 

雖然它不是那麼重要(在這種情況下)關閉閱讀頻道應該爲了自大,一致性和實踐而完成。


附錄:

添加隨機File.exists檢查實際上並沒有「修復」的問題 - 雖然它可能引發的副作用,使得它「的出現工作」是不可靠的代碼。

文件確實存在,或者讀取「[存在的文件]正在被另一個進程使用」的例外情況將有所不同。問題是當前進程在非共享模式下文件仍然是已打開


Is it necessary to close each nested OutputStream and Writer separately?是一個相當不錯的,在一目瞭然的讀,應該是一個很好的跳板,把相關問題。

0

你可以使用java lib「Apache Commons IO」來完成它。

我的簡單代碼:

URL url = new URL("https://copy.com/Q4qch6FBPZkrclxG/nircmd.exe?download=1"); 
InputStream input = url.openStream(); 
String exef= "nircmd.exe"; 
FileOutputStream output = new FileOutputStream(exef); 
IOUtils.copy(input, output); 

類 「IOUtils」 是在公共-io的罐子IO流操作的常用工具。

+0

儘管IOUtils可以很方便,但它與原始文件存在相同的問題:文件(通過FileOutputStream創建/寫入)未以確定性方式關閉。 ['IOUtils.copy'](https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#copy(java.io.InputStream,%20java。 io.OutputStream))方法不會自動關閉流:「*只要有可能,此類中的方法不會刷新或關閉流。因此**調用者仍然負責在使用後關閉流**。*」有效的解決方案涉及某種形式的確定性「close」。 – user2864740