我有2个文件夹,每个包含数十个batch file( *.bat
)。
batch file包含类似于任何一个的文本
del /f/q F:\MEDIA\IMAGE99\2010\270\z\4034\123.tif > nul del /f/q F:\MEDIA\IMAGE99\2010\266\z\3025\456.tif > nul del /f/q F:\MEDIA\IMAGE99\2010\267\z\3025\789.tif > nul del /f/q F:\MEDIA\IMAGE99\2010\286\z\9025\101.tif > nul del /f/q F:\MEDIA\IMAGE99\2010\272\z\6029\112.tif > nul del /f/q F:\MEDIA\IMAGE99\2010\258\z\4034\134.tif > nul
要么
rmdir /q F:\MEDIA\IMAGE99\2010\270\z\4034 rmdir /q F:\MEDIA\IMAGE99\2010\266\z\3025 rmdir /q F:\MEDIA\IMAGE99\2010\267\z\3025 rmdir /q F:\MEDIA\IMAGE99\2010\286\z\9025 rmdir /q F:\MEDIA\IMAGE99\2010\272\z\6029 rmdir /q F:\MEDIA\IMAGE99\2010\258\z\4034
在Java中,我列出每个File
夹中的每个批处理File
,然后在列表中循环,执行每个batch file,如下所示:
public static boolean batch(File file) { boolean handled = false; Process process = null; try { process = Runtime.getRuntime().exec("cmd /c start " + file); handled = process.waitFor() == 0; } catch (Exception ex) { // handling removed for example purposes } return handled; }
方法返回后,我删除batch file。
问题是,我的batch file中没有任何命令运行(我请求删除或删除的文件和文件夹不是),Java过程只是继续并删除batch file本身。
batch file位于文件夹d:\working\spaced folder\purge\batch_files\
写完了,我怀疑我的问题是,我将一个文件path与它的空间传递给exec()
方法。
我怀疑是对的吗? 如果是这样,我该如何解决呢? 如果不是,那么问题是什么?
我现在正在考虑Java:Execute / cmd / c start path-with-spaces \ program.exe 。
根据下面的评论,我已经改变了我的代码,但现在输出挂在waitFor()
和batch file没有被处理(我请求删除的文件仍然存在)。
码:
String commandString = "cmd /c \"" + file +"\""; logger.info("COMMAND " + commandString); process = Runtime.getRuntime().exec(commandString); logger.info("WAITING FOR " + commandString); handled = process.waitFor() == 0; logger.info("HANDLED " + commandString + " = " + handled);
输出:
COMMAND : cmd /c "d:\working\spaced folder\purge\deleteBatch\F_140.bat" WAITING FOR : cmd /c "d:\working\spaced folder\purge\deleteBatch\F_140.bat"
现在输出挂在
waitFor()
当使用Runtime.exec
从Java启动外部进程时,必须读取进程产生的任何输出,否则进程可能会阻塞( source:JavaDocs for java.lang.Process )。
改用ProcessBuilder
,然后调用redirectErrorStream
来合并标准输出流和错误流,然后读取process.getInputStream()
所有内容,直到到达EOF。 只有这样才能安全地调用waitFor
。
ProcessBuilder也将帮助解决空间问题,因为您必须自己将命令行分成单独的单词
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath());
使用Apache Commons-IO
package com.stackoverflow.windows; import java.io.File; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.NullOutputStream; public class Command { private Command() {} public static boolean batch(File file) { boolean handled = false; Process process = null; ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath()); pb.redirectErrorStream(true); try { process = pb.start(); IOUtils.copy(process.getInputStream(), new NullOutputStream()); handled = process.waitFor() == 0; } catch (Exception ignore) { // Only throws an IOException we're trying to avoid anyway, // and an expected InterruptedException // handled will be false } finally { if (process != null) { IOUtils.closeQuietly(process.getInputStream()); } } return handled; } }