代码之家  ›  专栏  ›  技术社区  ›  Some Name

有没有一种在Linux上用Java原子地编写文件的方法?

  •  0
  • Some Name  · 技术社区  · 6 年前

    O_TMPFILE 要使用指定的标志 open 系统调用创建无法通过任何路径打开的未命名临时文件。所以我们可以用它来“自动地”将数据写入文件 linkat 将给定文件转换为实际路径。根据OpenManPage,它的实现非常简单

    char path[1000];
    int fd = open("/tmp", O_TMPFILE | O_WRONLY, S_IWUSR);
    write(fd, "123456", sizeof("123456"));
    sprintf(path, "/proc/self/fd/%d", fd);
    linkat(AT_FDCWD, path, AT_FDCWD, "/tmp/1111111", AT_SYMLINK_FOLLOW);
    

    Files.createTempFile 做完全不同的事情。

    所谓原子写入,我的意思是,要么它不能被打开和读取,要么它包含所有需要写入的数据。

    0 回复  |  直到 6 年前
        1
  •  2
  •   Fire Lancer    6 年前

    我不相信Java有一个API来实现这一点,而且它似乎依赖于操作系统和文件系统的支持,所以JNI可能是唯一的方法,甚至只有在Linux上。

    我快速搜索了Cygwin所做的事情,似乎只是为了让软件正常工作,创建了一个随机名称的文件,然后将其从他们自己的目录列表中排除。

    我相信在纯Java中最接近的方法是在其他位置创建文件(有点像 /proc/self/fd/... 等效),然后在完成编写后,将其移动或从最终位置对其进行符号链接。要移动文件,需要将其放在同一文件系统分区上,这样实际上就不需要复制文件内容。正在监视中的文件的程序 /tmp/ 在移动或符号链接创建之前不会看到它。

    您可以使用用户帐户和文件系统权限来确保其他(非系统/根)程序最初无法看到该文件,即使它们试图查找您隐藏的位置。