我试图弄清楚File.renameTo()
在Java中的工作方式,并且在UnixFileSystem.java
中达到了以下方法(我在macOS上)。
private native boolean rename0(File f1, File f2);
我理解(如果我错了,请更正)native
表示JVM调用用另一种语言编写的代码/库。那么,我在哪里/如何或者有可能看到其实现?
我很好奇看到它的实现是为了确认是否可以在以下用例中使用它。
我需要在两个(或多个)不同的服务器中运行Java应用程序,这些服务器轮询同一目录(共享文件系统)中的文件,并且只有一个实例(服务器)应处理特定文件。每当任何服务器上的应用程序看到文件时,它都会尝试移至其他目录,并且如果移动成功(由File.renameTo()
方法返回的 boolean 确定),则该服务器将启动对这些文件内容进行处理(准确地说是批处理)。我对三个不同的实例轮询了一个目录(以每秒1000个文件的速度生成新文件)进行了快速测试,结果符合预期。我只想确认它是否可以缩放。
请注意,我并没有移动实际文件,而是移动了从源复制文件后创建的名为<actual-filename>.DONE
之类的零字节文件。
答案 0 :(得分:2)
AFAIK,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是文档:
重命名的一个有用的功能是,新名称的含义从原子上从以前存在的任何文件“原子地”更改为它的新含义(即称为旧名称的文件)。在旧含义和新含义之间没有“新名称”不存在的瞬间。如果操作过程中发生系统崩溃,则两个名称可能仍然存在;但是newname只要存在就永远是完整的。
也许您的代码只要不崩溃就可以安全使用,并且文件系统可以正常工作。但是,这可能取决于您所使用的文件系统(例如nfs)。
There's good another question在stackoverflow中,所以可能有帮助。