Java8 File / FileSystem(二) 源码解析

本文是《Java8 File / FileSystem(一) 源码解析》的延续,深入探讨了File类的更多方法实现,包括renameTo、setLastModified、权限设置、空间查询、compareTo、equals、hashCode以及ExpiringCache和DeleteOnExitHook的源码解析。内容涵盖文件重命名、修改文件时间戳、权限管理、磁盘空间检查以及JVM关闭时的文件删除机制。
摘要由CSDN通过智能技术生成

  目录

1、renameTo / setLastModified

2、setReadOnly / setWritable / setReadable / setExecutable / canExecute / canRead / canWrite

3、getTotalSpace / getFreeSpace / getUsableSpace

4、compareTo / equals / hashCode

5、ExpiringCache

6、DeleteOnExitHook 


     本篇博客继续上一篇《Java8 File / FileSystem(一) 源码解析》讲解File其他方法的源码实现。

1、renameTo / setLastModified

public boolean renameTo(File dest) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            //校验访问权限
            security.checkWrite(path);
            security.checkWrite(dest.path);
        }
        if (dest == null) {
            throw new NullPointerException();
        }
        //校验路径合法性
        if (this.isInvalid() || dest.isInvalid()) {
            return false;
        }
        return fs.rename(this, dest);
    }

//UnixFileSystem的实现
public boolean rename(File f1, File f2) {
        //清除路径解析的缓存
        cache.clear();
        javaHomePrefixCache.clear();
        //本地方法
        return rename0(f1, f2);
    }

public boolean setLastModified(long time) {
        if (time < 0) throw new IllegalArgumentException("Negative time");
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            //校验访问权限
            security.checkWrite(path);
        }
        if (isInvalid()) { //校验路径合法性
            return false;
        }
        //本地方法实现
        return fs.setLastModifiedTime(this, time);
    }

 涉及的本地方法实现都在UnixFileSystem_md.c中,其核心是用于文件重命名的rename函数和用于修改文件最后修改时间的utimes函数,如下:

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) {
            //调用rename函数,如果toPath在另一个目录下,则相当于移动文件并重命名,如果toPath已存在则rename失败
            if (rename(fromPath, toPath) == 0) {
                rv = JNI_TRUE;
            }
        } END_PLATFORM_STRING(env, toPath);
    } END_PLATFORM_STRING(env, fromPath);
    return rv;
}

JNIEXPORT jboolean JNICALL
Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
                                                jobject file, jlong time)
{
    jboolean rv = JNI_FALSE;

    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
        struct stat64 sb;
        //调用stat64函数获取文件属性
        if (stat64(path, &sb) == 0) {
            struct timeval tv[2];

            /* 之前的文件修改时间 */
            tv[0].tv_sec = sb.st_atime;
            tv[0].tv_usec = 0;

            /* 指定的文件修改时间,time是毫秒数 */
            tv[1].tv_sec = time / 1000;  //转换成秒数
            tv[1].tv_usec = (time % 1000) * 1000; //上述秒数对应的毫秒数
            //调用utimes函数修改文件属性
            if (utimes(path, tv) == 0)
                rv = JNI_TRUE; //修改成功,返回true
        }
    } END_PLATFORM_STRING(env, path);

    return rv;
}

 测试用例如下:

@Test
    public void test6() throws Exception {
        File file=new File("D:\\code\\test.txt");
        Calendar calendar=Calendar.getInstance();
        calendar.add(Calendar.HOUR,-1);
        System.out.println("setLastModified:"+file.setLastModified(calendar.getTimeInMillis()));
        System.out.println("lastModified:"+file.lastModified());
        //如果目标路径对应的文件已存在,则返回false
        System.out.println("renameTo:"+file.renameTo(new File("D:\\test2.txt")));
    }

2、setReadOnly / setWritable / setReadable / setExecutable / canExecute / canRead / canWrite

      这几个都是获取或者修改文件的可读可写可执行权限的,如下:

public boolean canRead() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        //本地方法实现
        return fs.checkAccess(this, FileSystem.ACCESS_READ);
    }

public boolean canWrite() {
        SecurityManager security = System.getSecurityManager(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值