Linux Api 具有 O_TMPFILE
标志,可通过 open
系统调用指定,创建无法通过任何路径打开的未命名临时文件。所以我们可以使用它来“atmoically”将数据写入文件,并将给定文件的 linkat
写入真实路径。根据打开的手册页,它可以简单地实现
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);
是否有 Java 替代方案(可能是非跨平台的)可以在不编写特定于 Linux 的 JNI 函数的情况下对文件进行原子写入? Files.createTempFile
做了完全不同的事情。
我所说的原子写入是指它要么无法打开和读取,要么包含所有需要写入的数据。
最佳答案
我不相信 Java 有这方面的 API,而且它似乎依赖于操作系统和文件系统的支持,所以 JNI 可能是唯一的方式,即使那样也只能在 Linux 上。
我快速搜索了 Cygwin 的功能,似乎只是为了让软件正常工作而进行的一些黑客攻击,创建一个具有随机名称的文件,然后仅将其从他们自己的目录列表中排除。
我相信在纯 Java 中最接近的是在其他位置创建一个文件(有点像 /proc/self/fd/...
等价物),然后当你完成编写后,将其移动或从最终位置进行符号链接(symbolic link)。要移动文件,您希望它位于同一个文件系统分区上,这样实际上不需要复制文件内容。在移动或创建符号链接(symbolic link)之前,监视 /tmp/
中文件的程序不会看到它。
您可以尝试使用用户帐户和文件系统权限,以确保没有其他(非 SYSTEM/root)程序最初可以看到该文件,即使他们试图查看您隐藏文件的位置也是如此。
关于java - 有没有办法在 Linux 上用 Java 原子地写入文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134619/