为什么不';Java执行Windows批处理文件时,我的Windows批处理文件不会处理吗?
我有两个文件夹,每个文件夹包含几十个批处理文件(为什么不';Java执行Windows批处理文件时,我的Windows批处理文件不会处理吗?,java,windows,batch-file,cmd,Java,Windows,Batch File,Cmd,我有两个文件夹,每个文件夹包含几十个批处理文件(*.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\IMAGE
*.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
或
在Java中,我列出了每个文件夹中的每个批文件
,并在列表中循环,执行每个批文件,如下所示:
公共静态布尔批处理(文件){
布尔值=假;
Process=null;
试一试{
process=Runtime.getRuntime().exec(“cmd/c start”+文件);
handled=process.waitFor()==0;
}捕获(例外情况除外){
//出于示例目的,已删除处理
}
处理退货;
}
方法返回后,我删除批处理文件
问题是,批处理文件中的任何命令都不会运行(我请求删除或删除的文件和文件夹不会运行),Java过程只是继续并删除批处理文件本身
批处理文件位于文件夹d:\working\spaced folder\purge\batch\u files\
写出来之后,我怀疑我的问题是我正在将一个带有空格的文件路径传递给exec()
方法
我的怀疑正确吗?如果是,我如何解决它?如果不是,问题可能是什么
既然我已经考虑过了,我现在就要调查一下
更新 根据下面的注释,我已经更改了代码,但是现在输出挂起在
waitFor()
,批处理文件没有被处理(我请求删除的文件仍然存在)
代码:
String commandString=“cmd/c\”+文件+“\”;
logger.info(“命令”+命令字符串);
process=Runtime.getRuntime().exec(commandString);
logger.info(“等待”+commandString);
handled=process.waitFor()==0;
logger.info(“已处理”+命令字符串+“=”+已处理);
输出:
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启动外部进程时,必须读取进程生成的任何输出,否则进程可能会阻塞()
改用ProcessBuilder
,调用redirectErrorStream
合并标准输出和错误流,然后从process.getInputStream()
读取所有内容,直到到达EOF。只有这样才能安全地调用waitFor
ProcessBuilder还将帮助解决空格问题,因为您必须自己将命令行拆分为单个单词
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath());
根据Ian Roberts的回答,使用的成功解决方案代码:
使用
如果批处理文件路径中有一个空格,那么是的,您将执行
del c:\foo bar
,而此时它应该是del“c:\foo bar”
。在文件
参数周围加上引号您可能不想使用启动
命令,因为如果这样做,调用.waitFor
将不会等待批处理文件完成。加引号的速度似乎较慢,但我没有看到从内部批处理调用中删除任何文件。我将尝试不使用start
,因为我认为这可能是问题所在。我最初没有开始
,但这就是我首先阅读StackOverflow获得答案的原因:PNo,现在它只是挂起处理文件。不知道会走多远;添加debug.No。通过cmd.exe删除目录的速度要比在Java中快很多倍。Windows有一个通配符删除系统调用:Java没有@OP我将从命令中删除“开始”。你想知道它是否有效,如果你使用“开始”,你就不会知道。我现在就试试,谢谢。仅供参考,ProcessBuilder pb=newprocessbuilder(“cmd”,“/c”,file.toString())
@JoshDM如果它是java.io.File
那么getAbsolutePath
比toString
更安全,因为它将为您提供完整的路径,即使文件本身是相对的。谢谢。这帮助我解决了这个问题。核对答案;使用的解决方案代码在单独的答案中公布。
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", file.getAbsolutePath());
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;
}
}