UnixFileSystem 的 Java File.renameTo() 实现

标签 java unix filesystems nio

我试图弄清楚如何File.renameTo()在 Java 中工作,我在 UnixFileSystem.java 中找到了以下方法(我使用的是 macOS)。

private native boolean rename0(File f1, File f2);

我明白了(如有错误请指正)native意味着 JVM 调用用另一种语言编写的代码/库。那么,我在哪里/如何可以或者是否可以看到它的实现?

我很好奇它的实现,以确认我是否可以将它用于我的以下用例。

我需要在两个(或更多)不同的服务器中运行 Java 应用程序,这些服务器轮询同一目录(共享文件系统)中的文件,并且只有一个实例(服务器)应该处理特定文件。每当任何服务器中的应用程序看到一个文件时,它都会尝试移动到其他目录,如果移动成功(由 File.renameTo() 方法返回的 boolean 值确定),则该服务器开始处理这些文件内容(准确地说是批处理)。我使用三个不同的实例轮询单个目录(以每秒 1000 个文件生成新文件)进行了快速测试,结果符合预期。我只是想确认它是否可以扩展。

请注意,我移动的不是实际文件,而是一个名为 <actual-filename>.DONE 的零字节文件。这是从源复制文件完成后创建的。

最佳答案

据我所知,Source of OpenJDK and Orale JDK are almost the same 。 因此,您可以找到 rename0 here 的实现:

#include <stdlib.h>

JNIEXPORT jboolean JNICALL
Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
                                    jobject from, jobject to)
{
    jboolean rv = JNI_FALSE;

    WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
        WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
            if (rename(fromPath, toPath) == 0) {
                rv = JNI_TRUE;
            }
        } END_PLATFORM_STRING(env, toPath);
    } END_PLATFORM_STRING(env, fromPath);
    return rv;
}

你可以看到它实际上调用了libc的rename。 由于大多数环境使用glibchere是文档:

One useful feature of rename is that the meaning of newname changes “atomically” from any previously existing file by that name to its new meaning (i.e., the file that was called oldname). There is no instant at which newname is non-existent “in between” the old meaning and the new meaning. If there is a system crash during the operation, it is possible for both names to still exist; but newname will always be intact if it exists at all.

也许你的代码只要不崩溃就是安全的,并且文件系统工作正常。但是,这可能取决于您使用的文件系统(例如 nfs)。

There's good another question在 stackoverflow 中,所以它可能会有所帮助。

关于UnixFileSystem 的 Java File.renameTo() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56472225/

相关文章:

linux - 如何从多个文件中剪切多列并将输出打印到不同的文件

Perl 根据命令行参数设置文件句柄

filesystems - docker,docker 容器的 aufs 根目录在哪里

Java Runtime.getRuntime().exec() 似乎正在覆盖 $PATH

java - 更新android中wifi广播接收器的ul响应

Java + Eclipse : Best way to store constants and tune them at runtime

mysql - 在C中将mysql数据库查询存储为变量

android - 在 Android Marshmallow 中遍历文件系统

java - 如何在 Mac OS X 上获取文件类型?

java - 需要帮助调试电子邮件代码