熟习Linux操作系统的同学应当知道Linux文件系统采取了inode - block的结构来表示和存储文件,inode包括了文件的元数据信息,block存储实际的文件内容。Linux把1切的IO都抽象成文件,那末目录和普通文件1样,也都是文件。每一个文件都有1个唯1的inode号。
可以用stat命令来查看1个文件的inode信息,比以下面这个文件 stat log.txt
可以看到Device是16777219d, inode号是1821216。这个文件内容是空的,所以Blocks为0
把这个log.txt 重命名为log2.txt,再履行stat log2.txt,可以看到只有文件名变了,其他的inode号这些元数据都没有变。
实际上普通文件的inode数据结构只存储1些元数据,不存储文件名的信息。那末文件名是存在哪里的呢,我们知道目录也是1种文件,那末它也有inode和block。普通文件的block块存储的是文件内容,目录的block块则存储了该目录下所有文件的inode号及对应的文件名等信息。
所以重命名1个文件,只是修改了它所在目录的目录block中的文件名信息,不会对文件的inode结构做任何修改。
既然inode这么有用,可以标识唯1的1个文件,那末Java如何获得这个inode信息呢。由于常常会遇到判断两个文件是不是是同1个文件的场景。
Java NIO提供了1个BasicFileAttributes接口来取得文件的Inode信息。它提供了1个 fileKey()方法,返回1个Object,这个Object包括了文件的deviceid和 inode号,可以唯1的标识1个文件。
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命令返回的结果是1致的
Creation Time : 2015-01⑵1T03:20:41Z
Last Access Time : 2015-01⑵1T03:38:01Z
Last Modified Time : 2015-01⑵1T03:20:41Z
Is Directory : false
Is Other : false
Is Regular File : true
Is Symbolic Link : false
Size : 0
Object Key : (dev=1000003,ino=1821216)