为什么当Java执行它们时,我的Windowsbatch file不能处理?

我有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 。


UPDATE

根据下面的评论,我已经改变了我的代码,但现在输出挂在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()); 

根据Ian Roberts的回答,成功解决方案的代码是:

使用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; } }