Java中的File.exists有多贵

Fra*_*fka 32 java filesystems directory file-io operating-system

我想知道它是如何File.exists()工作的.我不太清楚文件系统是如何工作的,所以我应该先开始阅读.

但是要获得快速的预先信息:

File.exists()如果在某个日志中注册了该路径和文件名,是对文件系统的单个操作的调用吗?或者操作系统是否获取目录的内容,然后通过它扫描匹配?

我认为这将取决于文件系统,但也许所有文件系统都使用快速方法?

我不是在谈论网络和磁带系统.让它保持ntfs,extX,zfs,jfs :-)

Cos*_*lis 16

测量必要的时间,看看自己.正如你所说,它绝对文件系统依赖的.

        long t1 = System.currentTimeMillis();
        ...Your File.exists call
        long t2 = System.currentTimeMillis();
        System.out.println("time: " + (t2 - t1) + " ms");
Run Code Online (Sandbox Code Playgroud)

您将看到它总是会给您不同的结果,因为它还取决于您的操作系统缓存数据的方式,负载等.

  • 它几乎完全取决于是否需要磁盘访问,在这种情况下,磁盘速度(以及是否繁忙)将是最重要的.如果您正在测试文件何时在缓存中,那么最好使用System.nanoTime(),因为它通常是亚毫秒. (2认同)
  • 你为什么要把'long`变成'long`,只是为了在减法时将它转换回`long`? (2认同)

Pet*_*rey 15

如果第一次执行此操作完全取决于文件系统.这是由操作系统完成的,Java并没有发挥任何作用.

在性能方面,在所有情况下都需要读取磁盘.这通常需要8-12毫秒.@Sven指出一些存储可能会变慢,但在性能很重要的情况下这种情况相对较少.如果这是一个网络文件系统,您可能会有额外的延迟(通常相对较小,但这取决于您的网络延迟).

相比之下,操作系统和Java所做的其他事情都非常短暂.

但是,如果检查文件是否重复存在,则可能不需要磁盘访问,因为信息可以缓存,在这种情况下,操作系统占用的时间和资源.File.exists()创建的对象中最大的一个(您不会认为它会)但是它会在每次调用时编码文件的名称,从而创建大量对象.如果将File.exists()置于紧密循环中,则每秒可以创建400MB的垃圾.:(

通过跟踪对文件系统所做的所有更改,日记文件系统的工作方式不同,但它们不会更改您读取文件系统的方式.


Vin*_*lds 8

大多数与文件相关的操作不是用Java执行的; 存在执行这些活动的本机代码.实际上,完成的大部分工作取决于FileSystem对象的性质(即支持File对象)以及OS中本机IO操作的底层实现.

为清楚起见,我将在OpenJDK 6中介绍实现的情况.File.exists()实现将实际检查推迟到FileSystem类:

public boolean exists() {
    ... calls to SecurityManager have been omitted for brevity ...
    return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
Run Code Online (Sandbox Code Playgroud)

FileSystem类是抽象的,并且存在所有支持的文件系统的实现:

package java.io;


/**
 * Package-private abstract class for the local filesystem abstraction.
 */

abstract class FileSystem
Run Code Online (Sandbox Code Playgroud)

注意包的私有性.Java Runtime Environment将提供扩展FileSystem类的具体类.在OpenJDK实现中,有:

  • java.io.WinNTFileSystem,用于NTFS
  • java.io.Win32FileSystem,用于FAT32
  • java.io.UnixFileSystem,用于*nix文件系统(这是一个责任非常广泛的类).

对于该getBooleanAttributes方法,所有上述类都委托给本机代码.这意味着在这种情况下,性能不受托管(Java)代码的约束; 文件系统的实现,以及正在进行的本机调用的性质对性能有更大的影响.

更新#2

根据更新的问题 -

我不是在谈论网络和磁带系统.让它保持ntfs,extX,zfs,jfs

好吧,那还不重要.不同的操作系统将以不同的方式实现对不同文件系统的支持.例如,Windows中的NTFS支持将与*nix中的支持不同,因为除了通过驱动程序与设备通信之外,操作系统还必须执行其簿记共享; 并非所有工作都在设备中完成.

在Windows中,您几乎总能找到文件系统筛选器驱动程序的概念,该驱动程序管理与其他文件系统筛选器驱动程序或文件系统通信的任务.这对于支持各种操作是必要的; 一个例子是使用过滤驱动程序来拦截IO调用的反病毒引擎和其他软件(即时加密和压缩产品).

在*nix中,您将拥有stat()系统调用,该调用将执行读取文件描述符的inode信息的必要活动.