java - 有没有办法在 Linux 上用 Java 原子地写入文件?

标签 java linux file io

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/

相关文章:

java - 为什么 javac 为最终字段插入 Objects.requireNonNull(this) ?

java - 组合框条目未显示在框架上

java - 在类路径中找到带有 TopLink : No META-INF/persistence. xml 的 JPA

python - Ubuntu 14.04 : command not found 中的 AWS Elastic Beanstalk (eb) 安装

linux - 根据字符位置读取文件内容

javascript - 不允许加载本地资源 : Ionic3(ios)

java - 声明静态 FileWriter 和 FileReader

java - 致命异常 : java. lang.VerifyError:来自导入的 jar 文件

c# - C#比较两个文件

c - 为什么先调用shm_unlink再调用shm_open?