进程 fork 时的 Java 文件管理

标签 java file fork

我的猜测是错误的,与答案无关。这个问题不再有效。请参阅my answer 。很抱歉这个糟糕的问题。

Tl;dr 版本

为什么 Java 进程无法找到某个文件,直到另一个进程(创建该文件的进程)完成执行。这可以解决吗?

加长版本

我有一个应用程序需要自行重新启动(它只需要重新启动,好吗?)。第一次,它创建一个文件,然后在那里序列化一个对象。这是通过 FileOutputStream 完成的/ObjectOutputStream组合,如下所述:

private static File serializeBootstrapInfoIntoFile(
    final BootstrapInfo info) throws IOException {

  final File tempFile = File.createTempFile("BobBootstrapInfo", null);
  final FileOutputStream fos = new FileOutputStream(tempFile);
  final ObjectOutputStream oos = new ObjectOutputStream(fos);
  oos.writeObject(info);

  // just being thorough
  oos.flush();
  oos.close();
  fos.flush();
  fos.close();

  return tempFile;
}

在此之后,我使用 System.exec() 创建另一个 java 进程。 -call,我将返回的 tempFile 的绝对路径传递给它作为系统属性。然后,另一个 java 进程应该打开该文件,并反序列化包含的对象。第一个进程保持 Activity 状态,直到生成的进程退出,因为它处理新进程的输出/错误流。

但是,问题是第二个进程似乎找不到该文件,并且总是在 FileNotFoundException 中终止。在反序列化期间(我已经用 file.exists() 确认了这一点)。

事后手动检查,该文件确实存在。另外,如果我手动运行传递给 System.exec() 的完全相同的命令行,运行良好。因此,我猜测第一个进程以某种方式设法从新进程中隐藏文件,或者无法实际将文件写入文件系统,即使流被刷新并关闭。我也尝试过 Thread.sleep(10000)在第一个线程上,让 IO 操作完成,但这没有一点帮助。

我做错了什么吗?或者这是 Java 的事情,或者可能是 OSX 的事情(我正在使用 atm 运行)?

评论回复

我运行的是 OS X 10.6.3,Java 版本是 1.6.0_20。

System.exec()参数是

java
-classpath
/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/bob7168396245507677201.tmp:/Users/wolfie/Documents/workspace/Bob/dist/lib/junit.jar:/Users/wolfie/Documents/workspace/Bob/dist/lib/bob.jar
-Dcache.location="/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4944987280015634213.tmp"
com.github.wolfie.bob.Bob

其中每一行都是字符串数组中的一个元素。 /var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp -file 是已创建的文件,并由另一个线程读取。 envpdir参数是 null .

整个堆栈跟踪是:

Exception in thread "main" com.github.wolfie.bob.BootstrapError: java.io.FileNotFoundException: "/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp" (No such file or directory)
    at com.github.wolfie.bob.Bob.getBootstrapInfo(Bob.java:186)
    at com.github.wolfie.bob.Bob.run(Bob.java:138)
    at com.github.wolfie.bob.Bob.main(Bob.java:95)
Caused by: java.io.FileNotFoundException: "/var/folders/dr/drDlHsguGvq0zF2Jtgn4S++++TI/-Tmp-/BobBootstrapInfo4606780571989099166.tmp" (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.(FileInputStream.java:106)
    at com.github.wolfie.bob.Bob.deserializeBootstrapInfoFromFile(Bob.java:265)
    at com.github.wolfie.bob.Bob.getBootstrapInfo(Bob.java:184)
    ... 2 more

最佳答案

从问题中看不到答案:我像这样定义了系统属性:

-Dcache.location="/foo/file.ext"

但该属性应该是相反的

-Dcache.location=/foo/file.ext

即没有引号。显然,当从命令行传递完全相同的参数时,这一点被忽略,可能是因为 Bash 以与 JVM 不同的方式处理它们。

很抱歉这个问题问得不好。

关于进程 fork 时的 Java 文件管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3126948/

相关文章:

python - 管理服务器上脚本的运行

java - ETL 工具 : GUIs vs. 框架

JButton 上的 Java ImageIcon 重复图像

java - 如何从 java 或 Android 中的字符串制作 XML 文档?

java - 读取文本文件并打印图形

c 多个文件描述符

c - fork与动态库交互

java - 将参数传递给 maven-exec-plugin 的内部命令失败

c - C中的读/写函数

unix - 当第一个子进程退出,然后父进程退出而不调用 wait 时会发生什么?