【问题标题】:How do you check to see if two different file reference "strings" refer to the same file?您如何检查两个不同的文件引用“字符串”是否引用同一个文件?
【发布时间】:2021-01-21 16:06:07
【问题描述】:

我们在纯 C 语言中有一个函数,旨在告诉我们两个文件引用是否引用同一个文件。现在它首先检查传入的参数是否实际上是相同的指针,如果不是,它会查看字符以查看字符串是否相同。但这并不能说明引用同一文件的不同方式的可能性。比如……

“/d1/d2/d3/theFile”与“../d3/theFile”相比

这些可能是同一个文件,也可能不是同一个文件,这取决于目录结构和当前参考点的位置。我想改进以下函数,以便能够检查对文件的字符串引用是否与另一个字符串引用相同的文件...

static bool is_same_file (const char *f1, const char *f2) {
    if (f1==f2)
        return true;
    return (0==strcmp(f1,  f2));
}

我想有可能尝试打开这两个文件并以某种方式使用它。但我不知道如何检查打开的文件是否是驱动器上的同一个物理文件,而不仅仅是碰巧存在于不同目录中的同一个文件。在 C# 中,有一个 FileInfo 类可用于根据该引用字符串查找文件,然后您可以比较完整的目录信息、文件名等。有没有办法在 C 中做类似的事情?

【问题讨论】:

  • 我认为没有任何独立于操作系统的方式。在 Unix 上,您可以使用 stat() 并检查 st_devst_ino 是否相同。
  • POSIX 具有 realpath 函数来返回路径名的规范化绝对路径名。这听起来与您描述的 C# FileInfo 类获取完整路径名的能力相似。
  • @IanAbbott realpath() 只保证返回“an 绝对路径名,其命名相同的文件,其解析不涉及'。' , '..' 或符号链接。”具有多个硬链接的文件将具有多个绝对路径名。 POSIX 系统中没有“规范”路径名。

标签: c file compare


【解决方案1】:

在 POSIX 系统上,您可以使用 stat() 检查它们在同一文件系统上是否具有相同的 inode 号。

您还应该检查代号,以处理由于文件被删除和新文件在两次调用之间获取其 inode 号而导致的竞争条件。

#include <sys/stat.h>

static bool is_same_file (const char *f1, const char *f2) {
    struct stat s1, s2;
    if (stat(f1, &s1) < 0)) {
        perror("stat f1");
        return false;
    }
    if (stat(f2, &s2) < 0)) {
        perror("stat f2");
        return false;
    }
    return s1.st_dev == s2.st_dev && s1.st_ino == st.st_ino && s1.st_gen == s2.st_gen;
}

【讨论】:

  • 这看起来很有希望。我会尝试一下,并将其标记为答案。谢谢你的信息!
  • 这似乎可以满足我的需求。不过,我需要稍微调整一下要测试的部分。应该作为同一个文件返回的东西没有。但这绝对让我走上了正确的道路。谢谢@Barmar
  • 你还需要测试什么?
  • 如果这不是真的正确,您应该发布更正确的答案。我不应该仅仅因为我给你指明了正确的方向而获得声誉。
  • 您还应该检查代号,以处理由于文件被删除和新文件在两次调用之间获取其 inode 号而导致的竞争条件。 多少次你应该这样做吗? ;-) 因为答案在返回时无效。您可以open() 文件,使用fstat() 检查inode 和设备号,然后关闭文件。答案仍然是,“他们在进行检查时是一样的”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 2018-08-30
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
相关资源
最近更新 更多