熟悉Linux操作系统的同学应该知道Linux文件系统采用了inode - block的结构来表示和存储文件,inode包含了文件的元数据信息,block存储实际的文件内容。Linux把一切的IO都抽象成文件,那么目录和普通文件一样,也都是文件。每个文件都有一个唯一的inode号。
可以用stat命令来查看一个文件的inode信息,比如下面这个文件 stat log.txt
可以看到Device是16777219d, inode号是1821216。这个文件内容是空的,所以Blocks为0
把这个log.txt 重命名为log2.txt,再执行stat log2.txt,可以看到只有文件名变了,其他的inode号这些元数据都没有变。
实际上普通文件的inode数据结构只存储一些元数据,不存储文件名的信息。那么文件名是存在哪里的呢,我们知道目录也是一种文件,那么它也有inode和block。普通文件的block块存储的是文件内容,目录的block块则存储了该目录下所有文件的inode号及对应的文件名等信息。
所以重命名一个文件,只是修改了它所在目录的目录block中的文件名信息,不会对文件的inode结构做任何修改。
既然inode这么有用,可以标识唯一的一个文件,那么Java如何获取这个inode信息呢。因为经常会遇到判断两个文件是否是同一个文件的场景。
Java NIO提供了一个BasicFileAttributes接口来获得文件的Inode信息。它提供了一个 fileKey()方法,返回一个Object,这个Object包含了文件的deviceid和 inode号,可以唯一的标识一个文件。
import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; public class INodeAttributes { public static void main(String[] args) throws Exception { Path path = Paths.get("/xxxxx/log.txt2"); BasicFileAttributes bfa = Files.readAttributes(path, BasicFileAttributes.class); System.out.println("Creation Time : " + bfa.creationTime()); System.out.println("Last Access Time : " + bfa.lastAccessTime()); System.out.println("Last Modified Time : " + bfa.lastModifiedTime()); System.out.println("Is Directory : " + bfa.isDirectory()); System.out.println("Is Other : " + bfa.isOther()); System.out.println("Is Regular File : " + bfa.isRegularFile()); System.out.println("Is Symbolic Link : " + bfa.isSymbolicLink()); System.out.println("Size : " + bfa.size()); Object objectKey = bfa.fileKey(); System.out.println("Object Key : " + bfa.fileKey()); } }
看到结果输出的deviceid和inode号和用Linux stat命令返回的结果是一致的
Creation Time : 2015-01-21T03:20:41Z Last Access Time : 2015-01-21T03:38:01Z Last Modified Time : 2015-01-21T03:20:41Z Is Directory : false Is Other : false Is Regular File : true Is Symbolic Link : false Size : 0 Object Key : (dev=1000003,ino=1821216)
时间: 2024-10-10 23:46:54