如何使用boost::filesystem获取inode?

3
我想检测是否已经看过某个文件,并希望用某些唯一的标识符来识别它。在Linux下,inode号和设备ID(参见stat()fstat())是一起的。我认为在Windows下也应该有类似的东西。
为了简单起见,boost::filesystem提供了方便的方法,例如我可以使用boost::filesystem::recursive_directory_iterator遍历目录树。 file_status告诉我它是否是一个常规文件,但不包括inode号。
我找到的最接近的东西是boost::filesystem::equivalent(),它需要两个路径。我想这也是最可移植的设计。
问题是我想把inode号放入数据库中以快速查找。我无法使用此函数进行操作,我必须使用数据库中已存在的所有路径调用equivalent()
我是否因可移植性原因而没有运气,boost将不会为我提供这样的信息?
(编辑)意图是在扫描文件夹树期间通过硬链接检测重复项。 equivalent()完全可以做到这一点,但我必须执行二次算法。

1
对于您的用例,您还应该知道,如果删除文件,则可以重新使用inode。这适用于Linux / Unix inode和Windows File ID / MFT记录。因此,如果您今天看到的inode与昨天看到的inode相同,则无意义。仅当您知道文件现在都存在时,inode才有用。另外,如果删除了一个文件,并创建了一个具有相同名称的相同文件,则inode可能会不同。这是“更新”文件的常见范例。因此,“相同的inode不同的时间”!=“相同的文件”,“不同的inode不同的时间”!=“不同的文件”。 - Ben
你说得对。在一次扫描中,这不是问题,你只需要了解“其他”硬链接(除了竞争条件)。但你指出的很正确,你不能在此之外依赖它们。 - Borph
1个回答

5
Windows CRT实现的stat始终使用零作为inode,因此您需要自己编写。这是因为在Windows上,FindFirstfileGetFileInformationByHandle快,因此stat使用FindFirstFile,它不包括inode信息。如果您不需要inode,那很好,可以提高性能。但是,如果需要,以下内容将有所帮助。
NTFS等效于INODE的是MFT记录号,也称为文件ID。它具有略微不同的属性,但在误差范围内可用于与INODE相同的目的,即确定两个路径是否指向同一文件。
您可以使用GetFileInformationByHandleGetFileInformationByHandleEx检索此信息。您首先必须调用CreateFile以获取文件句柄。
  • 您只需要拥有 FILE_READ_ATTRIBUTES 权限才能获取文件ID。
  • 您应该指定 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE
  • 您应该将操作设置为 OPEN_EXISTING

获取句柄后,使用其中一个 GetFileInformation 函数获取文件ID,然后关闭句柄。

您需要的信息可在 BY_HANDLE_FILE_INFORMATIONnFileIndexLownFileIndexHigh 成员中获得,或者如果正在使用 ReFS,则可能使用 128 位文件ID。要获取此信息,必须使用更新的函数。


严格来说,这是一条信息性评论,因为它根本没有回答问题:“如何使用boost::filesystem获取inode?” - sehe
1
@sehe,实际上他的问题不是“我如何使用boost做到这一点”,而是“我正在使用boost获取inode,但在Windows上它无法工作 - 我怎样才能让它在Windows上工作。如果不能使用boost来解决,那应该怎么办?” - Ben
这是有价值的信息,谢谢!sehe 是对的,它没有直接回答问题,但是“我可以使用 boost 来做吗?如果不行,那该怎么办?”非常到位。 - Borph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接