共计 1937 个字符,预计需要花费 5 分钟才能阅读完成。
本文由作者周梁伟授权网易云社区发布。
近日做的项目中涉及到多进程共同读写多个文件的问题,文件名和最后修改时间都是可能会被频繁修改的,因而识别文件的唯一性会产生相当的麻烦,于是专门再学习了一下文件系统对文件的组织管理方式。
一、文件在文件系统中的组织方式一块物理磁盘可以被分为若干个分区,分区的初始化操作就是在上面建立文件系统,如 ext3,ext4,ntfs 或 fat32 等都是文件系统的概念,还有网络文件系统如 NFS 等。同块磁盘上的不同分区也可以被指定不同的文件系统,文件系统对文件在磁盘上的数据读写方式做了抽象。一个文件系统中又被分为多个卷(Cylinder Group), 每个卷中最主要的部分是 inode 基路段和数据块段。i-node 结构唯一指定了一个文件实例,这个数据结构中包括了 inode 编号,所有包含的数据块的信息和该 inode 被引用的计数等。可以这么认为,要唯一识别的一个磁盘上的文件,只需要获得 inode-number 就可以了。文件或者目录则是存放在数据块中 directory block,其中包含了文件名和实体文件的 inode-number 等信息。文件名是可以随时被改变的,只要其中的 inode-number 没有发生改变,则指向的就是同一个文件。所以在应用程序中要判断文件是否相同如果依靠 filename 是不可靠的,只有获取到文件的 inode-number 才是可靠的。如在 log4j 这种日志应用中,日志文件的归档方式会使文件名不断发生变化,当前你 less 到的 app.log 在下一分钟可能就变成了 app.log.1。在这种场景下,程序只能通过获取文件 inode-number 来识别文件。
二、文件操作前面说了文件在磁盘上的存放是以 inode-number 为唯一 id 来区分的,在进程打开一个文件读写时,操作系统又会为文件分配一个 ” 指针 ” 来访问文件,而不是直接使用 inode-number。这个指针就是 FileDescriptor(下面简称 FD),FD 是一个动态的概念,是进程中调用 create 后 open 文件操作是返回的一个 Long 值,当文件关闭时这个 FD 也就失效了,所以同一个文件如果被打开两次获取到的 FD 会是不同的。进程打开文件的情况如下图所示,在进程中维护了一张表记录所有打开的文件,每一条记录表示一个 FileDescriptor,每个进程在开始时都默认打开了三个文件,FileDescriptor 分别是 0,1,2,既 stdin, stdout 和 stderr。FD 记录中包含了一张 FileTable,记录了文件的状态信息,offset 和 V -node 指针,V-Node 指针才真正指向了磁盘上的文件实体。(这里的 V -Node 是在 inode 之上抽象出来的概念,因为 i -node 在不同的文件系统中会有实现上的差异,V-Node 是为了统一不同文件系统的接口抽象出来的一层,在 Linux 中 V -Node 被称为 FileSystem independent INode,而 INode 称为 FileSystem dependent Inode,我们可以简单的理解为 V-Node 就是 INode)。图
当一个文件被多个进程共享读写时,可以看如下图:
这里进程 A 的 fd3 和进程 B 的 fd4 其实指向的是同一个实体文件,但是这两个进程维护了两张不同的文件表,维护了不同的 offset 位置。所以如果进程不是采用 append 方式写文件,两个进程写入的内容可能出现相互覆盖。这里也可能看到虽然 FD 不同,但是可以指向同一个实体文件,也说明了用 FD 来判断文件唯一性是不靠谱的。关于 FD 和 INode,还有关于缓存的重要注意事项。由于操作系统在接收到文件写请求时可能将写入内容放到缓存中,所以提供了 flush 和 sync 等操作来将缓存中的内容强制刷入磁盘。但是这两个操作作用是不同的。flush 会将数据刷入到 FileDescriptor 中,但是不会刷入 Inodesync/fsync/fdatasync 则会强制将 FD 中的数据刷入 Inode 中。
三、Java 操作文件的接口
最后需要注意的一点是,虽然在文件的存续期间,inode 可以认为是识别该文件的唯一标识,但是文件系统对 inode 有回收重用的机制,在文件被删除之后,原来的 inode 可以被分配给新创建的文件,这种情况下,如果一味以 inode 相同来判定新旧文件是不是同一个文件可能会出现错误; 应对这种情况确实也没有更好的办法,一种解决方法是,提取文件中部分内容的 MD5 或 SHA- 1 这种指纹信息作为标识,以 inode+md5 是否相同来决定是否是同个文件。
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请访问网易云社区。
文章来源:网易云社区