我有2个文件夹,每个文件夹包含数十个批处理文件(*.bat
)。
包含类似于
的文本的批处理文件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
,并在列表中循环,执行每个批处理文件,如下所示:
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;
}
方法返回后,我删除了批处理文件。
问题是,我的批处理文件中没有命令运行(我请求删除或删除的文件和文件夹不是),Java进程只是继续并删除批处理文件本身。
批处理文件位于文件夹d:\working\spaced folder\purge\batch_files\
写完之后,我怀疑我的问题是我将带有空格的文件路径传递给exec()
方法。
我的怀疑是否正确?如果是这样,我该如何解决?如果没有,问题可能是什么?
我现在要考虑Java: Execute /cmd /c start path-with-spaces\program.exe,我已经考虑过了。
根据下面的评论,我已经更改了我的代码,但现在输出挂起在waitFor()
并且批处理文件没有被处理(我请求删除的文件仍在那里)。
代码:
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"
答案 0 :(得分:3)
现在输出挂起
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());
答案 1 :(得分:0)
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;
}
}