下载后无法通过进程运行程序(Java)
下载程序(NirCmd)后,如下所示:
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);
然后像这样运行它:
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
# 1 楼答案
修好了!我是这样做的:
当它运行时:
它需要一个:
# 2 楼答案
关闭输出流。否则(至少在Windows中),它会在一段不确定的时间内对底层文件资源保持独占写入锁定
流应该通过以确定的方式调用^{} 来处理,以避免这个问题
如果
close
未被调用则流将“在将来某个不确定的时间关闭,当/如果终结器运行或程序退出”。正如所见,这种不确定性行为可能会导致错误和不稳定的行为为了简化操作,因为正确包装和调用
close
方法非常繁琐,可以使用try-with-resources语句:虽然关闭阅读频道并不重要(在本例中),但出于傲慢、一致性和实践的考虑,应该关闭阅读频道
增编:
添加一个随机的
File.exists
检查实际上并不能“修复”问题-,尽管它可能会触发一个副作用,使它“看起来有效”,但它是不可靠的代码文件确实存在,或者读取“[确实存在的文件]正被另一个进程使用”的异常将不同。问题是当前进程仍在非共享模式下打开
Is it necessary to close each nested OutputStream and Writer separately?是一个相当好的概览,应该是相关问题的良好起点
# 3 楼答案
可以使用java库“Apache Commons IO”来完成
我的简单代码:
类“IOUtils”是commons IO jar中用于IO流操作的常用工具