源码解读:File.listFiles

源代码:

    public File[] listFiles() {
        String[] ss = list();
        if (ss == null) return null;
        int n = ss.length;
        File[] fs = new File[n];
        for (int i = 0; i < n; i++) {
            fs[i] = new File(ss[i], this);
        }
        return fs;
    }

如图:

源码解析:

public File[] listFiles() {
    // 1. 调用list()方法获取当前目录下的文件名数组(String类型)
    String[] ss = list();
    
    // 2. 如果list()返回null(目录不存在/无权限/不是目录等),直接返回null
    if (ss == null) return null;
    
    // 3. 获取文件名数组的长度
    int n = ss.length;
    // 4. 创建与文件名数组长度相同的File对象数组
    File[] fs = new File[n];
    
    // 5. 遍历所有文件名
    for (int i = 0; i < n; i++) {
        // 6. 为每个文件名创建File对象:
        //    ss[i]        : 文件名(相对路径)
        //    this         : 当前File对象(父目录)
        //    组合成完整路径: 父目录路径 + 文件分隔符 + 文件名
        fs[i] = new File(ss[i], this);
    }
    
    // 7. 返回File对象数组
    return fs;
}

解读太抽象了,我们具体来说

假设当前File对象表示目录“/home/user”,并且该目录下有两个文件:“a.txt”和“b.txt”。

那么,`list()`方法返回的字符串数组ss为:["a.txt", "b.txt"]。

然后,我们创建一个长度为2的File数组。

在循环中,对于每个文件名,我们创建新的File对象:

  1.         第一个:new File("a.txt", this) -> 相当于路径为“/home/user/a.txt”
  2.         第二个:new File("b.txt", this) -> 相当于路径为“/home/user/b.txt”

因此,返回的File数组就包含了这两个文件的File对象。

但是,这里有一个重要的点:`list()`方法返回的数组中的每一项(文件名)是依赖于底层文件系统的。例如,在Unix系统上,隐藏文件(以'.'开头的文件)也会被包含在内,而在某些系统上可能不会包含特殊文件(如设备文件、命名管道等)或符号链接,这取决于底层操作系统的实现。

另外,`listFiles()`方法返回的数组中的顺序是不确定的,通常与底层文件系统返回的顺序一致,因此不能依赖于特定的顺序。 最后,需要注意的是,如果目录中没有任何文件,则`list()`方法返回一个长度为0的数组(不是null),那么`listFiles()`方法就会返回一个长度为0的File数组。

总结调用过程:

  • - 检查当前File对象是否是一个可读的目录(这一步在`list()`方法内部完成,如果不符合条件则返回null)。
  • - 获取目录下的所有文件名(字符串形式)。
  • - 将这些文件名转换为相对于当前目录的File对象。
  • - 返回File数组。 如果调用者没有足够的权限访问该目录,或者该File对象不是一个目录,那么`list()`方法返回null,因此`listFiles()`也返回null。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值