0

我有 java cde 将类文件放在一起:

    List<String> args = new ArrayList<String>();
    String path = FileSystemUtils.JavaBin() + "\\jar.exe";
    args.add(path);
    args.add("-cfv");
    args.add(jarName);
    args.addAll(FileSystemUtils.getAllFiles(directory, ".class"));
    ProcessBuilder pb = new ProcessBuilder(args);
    File wd = new File(directory);
    pb.directory(wd);
    Process p = pb.start();
    //Waiting for process to exit
    p.waitFor();
    int res = p.exitValue();

这段代码效果很好。但是,在某些计算机上 - 不是在所有计算机上,当有 7 个以上的文件时p.waitFor();,即使创建了 jar,也不会返回。

查看任务管理器,jar.exe 确实没有终止.... 可能是什么原因?从命令行手动运行相同的命令会立即退出。

这似乎很奇怪。有人有任何提示吗?

4

1 回答 1

0

自己找到了解决方案。显然,如果您ProcessBuilder.start在 Java 中使用来启动外部进程,则必须使用其 stdout/stderr,否则外部进程会挂起。

这是因为操作系统创建了一个管道。在这方面,所有类似 Unix 的操作系统和 Windows 的行为都是相同的:在父子节点之间创建一个 4K 的管道。当该管道已满时(因为一侧没有读取),写入过程会阻塞。

似乎当有 7 个以上的文件时 jar.exe 消耗 4K,然后卡住了。

过程的Javadoc:

默认情况下,创建的子进程没有自己的终端或控制台。它的所有标准I/O(即stdin、stdout、stderr)操作都将被重定向到父进程,在那里可以通过使用getOutputStream()、getInputStream() 和getErrorStream() 方法获得的流来访问它们。父进程使用这些流向子进程提供输入并从子进程获取输出。由于部分原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。

于 2013-08-29T12:59:50.163 回答