为了账号安全,请及时绑定邮箱和手机立即绑定

UnixFileSystem 的 Java File.renameTo() 实现

UnixFileSystem 的 Java File.renameTo() 实现

qq_笑_17 2023-01-05 17:19:04

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

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

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

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

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

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


查看完整描述

1 回答

?
神不在的星期二

TA贡献1699条经验 获得超6个赞

AFAIK,OpenJDK 和 Orale JDK 的来源几乎相同rename0 因此,您可以在此处找到实现:

#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这里是文档:

rename 的一个有用特性是,newname 的含义从任何以前存在的具有该名称的文件“原子地”更改为它的新含义(即,名为 oldname 的文件)。newname 在旧含义和新含义“之间”的任何时刻都不存在。如果在运行过程中出现系统崩溃,则有可能两个名字都还存在;但如果 newname 存在的话,它将永远是完整的。

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



查看完整回答
反对 回复 2023-01-05

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信