【问题标题】:How to get the inode with boost::filesystem?如何使用 boost::filesystem 获取 inode?
【发布时间】:2014-05-09 03:59:24
【问题描述】:

我想检测我是否已经看到了一个文件,并想用一些独特的东西来识别它。在 Linux 下,inode 编号与设备 ID 一起出现(请参阅 stat() 或 fstat())。我假设在 Windows 下我会找到类似的东西。

为了简单起见,boost::filesystem 提供了方便的方法,例如我可以使用boost::filesystem::recursive_directory_iterator 来遍历目录树。 file_status 告诉我它是否是常规文件,但不是 inode 编号。

我发现最接近的是boost::filesystem::equivalent() 采用两条路径。我想这也是最便携的设计。

问题是我想将 inode 编号放入数据库中以便快速查找。我无法使用此函数执行此操作,我必须调用 equivalent() 并使用数据库中已存在的所有路径。

我是不是运气不好,由于便携性原因,boost 不会向我提供此类信息?

(编辑)目的是在一次扫描文件夹树期间通过硬链接检测重复项。 equivalent() 正是这样做的,但我必须做一个二次算法。

【问题讨论】:

  • 对于您的用例,您还应该知道如果文件被删除,inode 可以重新使用。 Linux/unix inode 和 Windows 文件 ID/MFT 记录都是如此。因此,如果您今天看到的 inode 与您昨天看到的 inode 相同,那没有任何意义。仅当您知道 both 文件现在 存在时,inode 才有用。此外,如果删除了一个文件,并创建了一个具有相同名称的相同文件,则 inode 可能会有所不同。这是“更新”文件的常见范例。所以“相同的inode不同的时间”!=“相同的文件”和“不同的inode不同的时间”!=“不同的文件”。
  • 你是对的。在一次扫描期间,这不是问题,您只需了解“其他”硬链接(除了竞争条件)。但你指出,除此之外你不能依赖它们。

标签: c++ boost


【解决方案1】:

stat 的 Windows CRT 实现始终使用零作为 inode,因此您必须自己滚动。这是因为在 Windows 上FindFirstfile 比GetFileInformationByHandle 快,所以stat 使用FindFirstFile,它不包含inode 信息。如果您不需要 inode,那就太好了,性能获胜。但如果你这样做了,以下内容会有所帮助。

与 INODE 等效的 NTFS 是 MFT 记录号,也称为文件 ID。它的属性略有不同,但在误差范围内可用于与 INODE 相同的目的,即识别两个路径是否指向同一个文件。

您可以使用GetFileInformationByHandle 或GetFileInformationByHandleEx 来检索此信息。您首先必须调用CreateFile 来获取文件句柄。

  • 您只需要FILE_READ_ATTRIBUTES 权限即可获取文件ID。
  • 您应该指定FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE
  • 您应该指定OPEN_EXISTING 作为处置。

获得句柄后,使用 GetFileInformation 函数之一获取文件 ID,然后关闭句柄。

您需要的这些信息在BY_HANDLE_FILE_INFORMATIONnFileIndexLow 和nFileIndexHigh 成员中提供,或者如果正在使用 ReFS,则可能正在使用 128 位文件 ID。要获得这个,你必须使用更新的函数。

【讨论】:

  • 严格来说,这是一条信息性评论,因为它根本没有回答问题:“如何使用 boost::filesystem 获取 inode?”
  • @sehe,实际上他的问题不是“如何使用 boost让它在 Windows 上运行。如果不能,我可以使用 boost 来实现吗?"。
  • 这是很有价值的信息,谢谢! sehe 是对的,它没有直接回答问题,而是“我可以使用 boost 来做吗,如果不能,那怎么做?”击中钉子。
猜你喜欢
  • 2015-03-26
  • 2012-09-20
  • 2012-04-27
  • 2011-06-14
  • 2016-06-02
  • 2012-01-25
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
相关资源
最近更新 更多