关于文件的INode与Java中的文件操作接口
本文由作者周梁伟授权网易云社区发布。
近日做的项目中涉及到多进程共同读写多个文件的问题,文件名和最后修改时间都是可能会被频繁修改的,因而识别文件的唯一性会产生相当的麻烦,于是专门再学习了一下文件系统对文件的组织管理方式。
一、 文件在文件系统中的组织方式
一块物理磁盘可以被分为若干个分区,分区的初始化操作就是在上面建立文件系统,如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中,但是不会刷入Inode
sync/fsync/fdatasync则会强制将FD中的数据刷入Inode中。
三、 Java操作文件的接口
最后需要注意的一点是,虽然在文件的存续期间,inode可以认为是识别该文件的唯一标识,但是文件系统对inode有回收重用的机制,在文件被删除之后,原来的inode可以被分配给新创建的文件,这种情况下,如果一味以inode相同来判定新旧文件是不是同一个文件可能会出现错误;应对这种情况确实也没有更好的办法,一种解决方法是,提取文件中部分内容的MD5或SHA-1这种指纹信息作为标识,以inode+md5是否相同来决定是否是同个文件。
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请访问网易云社区。
文章来源: 网易云社区
关于文件的INode与Java中的文件操作接口相关推荐
- java 检测目录下的文件_如何在Java中检查文件是目录还是文件
java 检测目录下的文件 java.io.File class contains two methods using which we can find out if the file is a d ...
- java识别文件类型_在Java中识别文件类型
我使用 Apache Tika,它使用魔术字节模式和globbing提示(文件扩展名)来识别文件类型,以检测MIME类型.它还支持对文件内容的其他解析(我不真正使用). 以下是一个简单而肮脏的例子,说 ...
- java中打开文件显示_从java程序中打开任何文件
在 java中打开文件似乎有点棘手 – 对于.txt文件,必须将File对象与Scanner或BufferedReader对象结合使用 – 对于图像IO,必须使用 ImageIcon类 – 如果要打开 ...
- java语言 文件上传,java中实现文件上传的方法
java中实现文件上传的方法 发布时间:2020-06-19 10:29:11 来源:亿速云 阅读:86 作者:Leah 这篇文章给大家分享的是java中实现文件上传的方法,相信大部分人都还没学会这个 ...
- java中读取文件的方法
总结一下java中读取文件的方法: 方法一(逐行的读取文件内容): private FileReader fileReader; private BufferedReader bufferedRead ...
- 写文件 追加_总结Java中创建并写文件的5种方式
在Java中有很多的方法可以创建文件写文件,你是否真的认真的总结过?下面小编就帮大家总结一下Java中创建文件的五种方法. 在java中有很多的方法可以创建文件写文件,你是否真的认真的总结过?下面笔者 ...
- 在Java中确定文件类型
以编程方式确定文件的类型可能非常棘手,并且已经提出并实现了许多基于内容的文件标识方法. Java中有几种可用于检测文件类型的实现,其中大多数很大程度上或完全基于文件的扩展名. 这篇文章介绍了Java中 ...
- 服务器测试文件怎么创建,如何创建一个“FTPS”模拟服务器以单元测试Java中的文件传输...
我有一个创建FTPS连接的CreateFTPConnection类.使用此连接传输文件.这里是TransferFile类的代码如何创建一个"FTPS"模拟服务器以单元测试Java中 ...
- java 创建文件夹的方法_java中创建文件夹的方法
java中创建文件夹的方法 发布时间:2020-06-10 11:46:49 来源:亿速云 阅读:461 作者:Leah 这篇文章给大家分享的是java中创建文件夹的方法.小编觉得挺实用的,因此分享给 ...
最新文章
- docker配置国内镜像源
- Java集合:set的遍历方式
- 未正确安装master data services_GP数据库安装
- Objective-C 学习记录6--dictionary
- Windows Phone 7开发一月谈(3)
- mysql innodb 间隙锁_Mysql innodb 间隙锁
- [转]Http请求中Content-Type讲解以及在Spring MVC中的应用
- JAVA中“:”的用法详解
- hive 建表_大数据面试必备 | Hive数据仓工具面试题!
- php做抖音在微信中播放,微信小程序实现抖音播放效果的实例代码
- 六年级上册计算机教材分析,人教版六年级上册数学教材分析
- CentOS 7 yum update 报错 Failed to connect to 2404:6800:4012::200e: Network is unreachable
- 响应绿色建设 智慧城市应寻找低碳发展
- android不root截图,某安卓手机无需root就可以被任意应用截屏及解决方案
- 图库类小程序服务器配置,小程序生成图片库
- 气象雷达在民航中的运用
- 面向维基百科的领域知识演化关系抽取
- 华为认证网络工程师认证考试笔试题
- Java 编辑PPT SmartArt图形
- 如何快速的把图片转换为PDF文件格式
热门文章
- Java 函数传递对象是引用传递还是值传递?
- el表达式 多条件判断
- 2018年上半年读者最喜爱的异步新书TOP50
- php中js验证表单,js实现表单验证
- 技术支持和研发哪个好_考拉海购技术支持的前世今生,聊聊家常“黑历史”
- linux中 字符串,linux内核驱动中对字符串的操作
- [设计模式-行为型]迭代器模式(Iterator)
- Linux下VNCSERVER的使用介绍
- java oracle数据备份_Java后台备份oracle数据库脚本
- android自定义工具栏,Android工具栏中的自定义图标