我从我的Java程序运行一个bash脚本,它接收一大块数据,操作它并将其拆分。
这不是bash脚本是否有效的问题 - 我可以在目录中看到拆分文件。
在data /
中说原始文件是“bigFile”然后
try
{
Process proc = Runtime.getRuntime().exec("bash " + SCRIPT_DIR + "/" + SPLIT_SCRIPT_NAME + " " + args[_MESSAGES_PER_UPLOAD_] + " " + args[_MAXIMUM_MESSAGES_PER_FEED_] + " " + (60000*Integer.parseInt(args[_DURATION_BEFORE_EACH_UPLOAD_IN_MINUTES_])/Integer.parseInt(args[_DURATION_OF_EACH_FEED_IN_MILLISECONDS_])));
proc.waitFor();
}
catch(IOException e) { error(e); }
String fileNames;
File folder = new File(DATA_DIR);
File[] filesToUpload = folder.listFiles();
for (int i = 0; i < filesToUpload.length; ++i)
if (filesToUpload[i].isFile())
{
fileNames = filesToUpload[i].getName();
System.out.println(fileNames);
}
将打印bigFile,而不是......
$ ls data /
dataChunk_00000 dataChunk_00001 dataChunk_00002 dataChunk_00003 dataChunk_00004 dataChunk_00005 dataChunk_00006 dataChunk_00007 dataChunk_00008 dataChunk_00009 dataChunk_00010 dataChunk_00011 dataChunk_00012 dataChunk_00013 dataChunk_00014 dataChunk_00015 dataChunk_00016 dataChunk_00017 dataChunk_00018 dataChunk_00019 dataChunk_00020 dataChunk_00021 dataChunk_00022 dataChunk_00023 dataChunk_00024 dataChunk_00025 dataChunk_00026 dataChunk_00027
应该如此。我猜这是编译器优化或其他什么。
编辑:如果有人可以向我解释为什么proc.waitFor()不起作用和/或更好的解决方法,我会非常感激。
答案 0 :(得分:3)
这个问题不是编译器优化或类似的东西。
因为你在前面用“bash”调用你的脚本。这会导致进程fork - 所以你的bash命令会立即成功返回,但你的脚本会继续在后台运行并终止。
proc.waitFor()没有什么可以等待的,java程序的其余部分在文件被“拆分”之前执行。
答案 1 :(得分:2)
您无法使用java更改目录。 如果你想“模拟”它,你需要做的就是设置属性“user.dir”。
答案 2 :(得分:1)
我猜你的bash脚本正在从它自己的进程/线程异步执行操作。这意味着脚本在工作完成之前完成执行。这仍将通过waitFor()检查并继续执行代码。
编辑: Kal的答案更清楚地解释了这一点,并且首先发布了。问题在于您使用bash命令来执行脚本。
答案 3 :(得分:0)
我怀疑你的论据并没有全部传递给你的剧本。
将所有参数放在ArrayList实例中,将实例传递给ProcessBuilder,然后在构建器实例上调用start
方法,该方法返回调用waitFor
的proc。
这里有Scala代码示例,用于显示我的意思(如果您真的感兴趣,我可以将其移植到Java中;):
import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder }
import java.util.{ArrayList => JArrayList, List => JList, Map => JMap}
import java.io.{InputStreamReader, BufferedReader}
def call(args: String*) = {
val command: JList[String] = new JArrayList[String]()
args.foreach {arg =>
command.add(arg)
}
//log.debug("argument list: %s", command.toString)
val builder = new JProcessBuilder(command)
val proc: JProcess = builder.start()
proc.waitFor()
val read = new BufferedReader(new InputStreamReader(proc.getInputStream()));
val sb: StringBuffer = new StringBuffer()
while(read.ready()) {
sb.append(read.readLine)
}
// sb now has the output of the called process...
val exitValue: Int = proc.exitValue
// http://stuffthathappens.com/blog/2007/11/28/crash-boom-too-many-open-files/
read.close
proc.destroy
(exitValue, sb.toString) // return it
}
REPL中的示例调用:
scala> call("date")
res156: (Int, java.lang.String) = (0,Mon 18 Jul 2011 22:29:58 BST)
答案 4 :(得分:0)
此计划有许多错误的假设:
解决问题的更好方法是仔细阅读File API,并尽可能使用绝对路径。当你在shell中时,'当前目录'是非常有用的东西,但是对于应用程序来说它最终会更加混乱,所以越早将它解析为绝对路径 - 越好。