我有这个代码:
try {
// Create a temporary file
Path tmpFilePath = Files.createTempFile("tmp-errors", ".log");
// Create a ProcessBuilder and redirect the error stream to the temporary file
ProcessBuilder pb = new ProcessBuilder("my-command")
.redirectError(Redirect.appendTo(tmpFilePath.toFile()));
// Start the process
Process process = pb.start();
// log the erros into this thread
Files.readAllLines(tmpFilePath,StandardCharsets.ISO_8859_1).forEach(LOGGER::error);
// Delete the temporary file after the process completes
Files.delete(tmpFilePath);
} catch (IOException | InterruptedException e) {
// Handle the exception
e.printStackTrace();
}
我想使用Process Builder执行外部进程,收集来自外部进程的错误使用redirectError()方法,从临时文件中收集这些错误,并将它们记录在当前线程中,最后删除临时文件。
但我一直得到这个错误:
The process cannot access the file because it is being used by another process
我认为文件仍然被Process Builder锁定,但我找不到如何释放它!
2条答案
按热度按时间pkbketx91#
调用ProcessBuilder.start()方法。该方法返回一个Process示例,在it's documentation中,您可以看到
因此,您的进程可能是由操作系统启动的,但由于I/O限制而被阻塞。通过阅读STDOUT和STDERR流来解决这个问题,直到您的进程完成。或者重定向流,如下所示:
一旦进程终止,您应该能够正常访问或删除临时文件。
km0tfn4u2#
正如在注解和其他答案中提到的,您的子进程将写入临时文件,直到它退出,所以您必须在尝试删除之前调用
waitFor()
等待进程退出。如果
waitFor()
没有返回或者子进程似乎冻结了,那么可能的后续问题是stdout缓冲区已满。为了确保正确的终止,在阅读+删除临时文件之前,添加stdout consumer来读取process.getInputStream()
并等待进程:明显冻结的另一个原因是当子进程使用控制台输入时。如果是这种情况,您还应在
start()
之后和阅读STDOUT之前发出输入结束信号:如果每次都创建临时文件,则可以删除追加模式的使用,将
redirectError
替换为.redirectError(tmpFilePath.toFile())
。