Java File.renameTo() UnixFileSystem 的实现
Java File.renameTo() Implementation for UnixFileSystem
我试图弄清楚 File.renameTo()
在 Java 中是如何工作的,我在 UnixFileSystem.java
中找到了以下方法(我在 macOS 上)。
private native boolean rename0(File f1, File f2);
我理解(如有错误请指正)native
表示 JVM 调用 code/library 是用另一种语言编写的。那么,where/how 我可以或是否可以看到它的实现?
我很想看看它的实现,以确认我是否可以将它用于我的以下用例。
我需要 运行 一个 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
。
由于大部分环境使用glibc
,here的文档:
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 在 Whosebug 中,所以它可能会有所帮助。
我试图弄清楚 File.renameTo()
在 Java 中是如何工作的,我在 UnixFileSystem.java
中找到了以下方法(我在 macOS 上)。
private native boolean rename0(File f1, File f2);
我理解(如有错误请指正)native
表示 JVM 调用 code/library 是用另一种语言编写的。那么,where/how 我可以或是否可以看到它的实现?
我很想看看它的实现,以确认我是否可以将它用于我的以下用例。
我需要 运行 一个 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
。
由于大部分环境使用glibc
,here的文档:
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 在 Whosebug 中,所以它可能会有所帮助。