我在Linux上,文件索引数据库。 目前我使用的文件路径作为标识符。 但是,如果一个文件被移动/重命名,它的路径改变,我无法将数据库记录相匹配的新文件,并必须删除/重新备案。 更糟的是,如果一个目录被移动/重命名,然后我不得不删除/重新创建的所有文件和嵌套的目录记录。
我想用索引节点号作为唯一文件标识符,但如果文件被删除,另一个文件中创建的索引节点号可以重复使用。
所以,我不知道我是否可以使用一对{inode,crtime}
作为唯一文件标识符。 我希望用i_crtime对EXT4和CREATION_TIME上NTFS。 在我有限的测试(ext4的)索引节点和crtime做,的确,重命名或同一文件系统内移动文件或目录时保持不变。
所以,问题是,是否有这样的情况,当一个文件索引节点或crtime可能会改变。 例如,可以fsck的或碎片整理或分区大小调整变化的inode或crtime或文件?
有趣的是http://msdn.microsoft.com/en-us/library/aa363788%28VS.85%29.aspx说:
- “ 在NTFS文件系统,文件保持相同的文件ID,直到它被删除”。
但是也: - “ 在某些情况下,一个文件的文件ID可以随时间而改变。”
那么,什么是他们提到的那些情况?
请注意,我研究了类似的问题:
- 如何确定在linux文件的唯一性?
- 执行“MV A B”:请问“索引节点”是否会改变?
- 最好的方法来检测移动或重命名在Linux文件?
但他们没有回答我的问题。
- {device_nr,inode_nr}是用于在系统内一个inode的唯一标识符
- 文件移动到不同的目录中不改变其inode_nr
- Linux的
inotify
界面,您可以监视到的inode的变化(无论是文件或目录)
附加说明:
- 跨文件系统移动文件的处理方式不同。 (这是逸岸复制+删除)
- 联网的文件系统(或一个安装NTFS)不能总是保证inodenumbers的稳定性
- 微软是不是 UNIX供应商,它的文档不包括Unix或它的文件系统,并且应该被忽略(除了NTFS的内部)
额外的文本:旧的Unix adagium“一切皆文件”其实应该是:“一切都是一个inode”。 索引节点承载所有关于除了名称的文件(或目录,或者一个特殊的文件)的元信息 。 文件名实际上只是碰巧链接到特定inode的一个目录条目。 移动文件意味着:创建一个新的连接到相同的inode,最终删除该链接到它的旧目录条目。 索引节点metatata可以通过获得stat()
和fstat()
和lstat()
系统调用。
i节点的UNIX中的分配和管理取决于文件系统。 因此,对于每个文件系统,答案可能会有所不同。
对于Ext3文件系统(最流行的),i节点被重用,因而不能被用作唯一文件标识符,也不是根据任何可预测的模式不重用发生。
在Ext3的,i节点在一个位向量跟踪,每个比特代表一个单一的i节点号。 当i节点被释放,它的位设置为零。 当需要一个新的i节点,所述比特向量中搜索第一零位和i节点号(其可能先前已被分配给另一文件)被再利用。
这可能导致天真的结论是号码最小的可用i节点将是一个重复使用。 然而,Ext3文件系统是复杂的,高度优化的,所以没有假设应进行有关何时以及如何节点号可重复使用,即使他们显然会。
从ialloc.c的源代码,其中i节点分配:
有分配一个inode两个策略。 如果新的索引节点是一个目录,那么前向搜索用于与两个自由空间和低的目录到索引节点比一个块组作出; 如果失败,那么他团体高于平均水平的自由空间,已选择该组使用目录最少。 对于其他索引节点,从父目录的块组向前搜索找到一个空闲的inode。
管理这个时,Ext3的源代码被称为ialloc和最终版本在这里: https://github.com/torvalds/linux/blob/master/fs/ext3/ialloc.c
我猜DB应用程序将需要考虑该文件是从备份受恢复的情况下,这将保留文件crtime,但不是inode编号。