【问题标题】:Can I check if two FILE* or file descriptor numbers refer to the same file?我可以检查两个 FILE* 或文件描述符编号是否引用同一个文件吗?
【发布时间】:2012-09-19 20:39:38
【问题描述】:

我有一个从文件读取并写入文件的程序。我想阻止用户为两者指定相同的文件(出于显而易见的原因)。假设第一条路径在char* path1 中,第二条路径在char* path2 中。我可以fopen() 两条路径,在每条路径上调用fileno() 并获得相同的号码吗?

解释得更清楚:

char* path1 = "/asdf"
char* path2 = "/asdf"

FILE* f1 = fopen(path1, "r");
FILE* f2 = fopen(path2, "w");

int fd1 = fileno(f1);
int fd2 = fileno(f2);

if(fd1 == fd2) {
  printf("These are the same file, you really shouldn't do this\n");
}

编辑:

我不想比较文件名,因为使用/asdf/./asdf 之类的路径或使用符号链接很容易将其击败。最终,我不想将我的输出写入我正在读取的文件中(可能会导致严重的问题)。

【问题讨论】:

  • 没有。在任何合理实现的 POSIX 系统上,对 open 的新调用将返回一个新的文件描述符。真的,为什么不直接比较文件名本身是否相等?
  • 一般情况下不会。什么是“同一个文件”?两个不同的文件名(路径)可以通过硬链接引用磁盘上的同一块数据。相同的路径和文件也可以引用两个不同的数据块。如何?创建文件 A,打开文件 A,删除文件 A——不关闭它。现在创建相同的文件名A,再次打开它——它是一个不同的同名文件。两个打开的描述符以相同的名称打开,引用不同的文件。
  • 为什么你不能只比较他/她给出的文件路径和如果它们相同的错误?
  • 刚试了一下,即使引用磁盘上的同一个文件,两个文件描述符也不一样。
  • 仅供参考,您也可以比较文件路径,方法是使用 realpath 获取解析所有符号链接的规范绝对路径。如果您确实使用realpath,请注意@clintp 的警告:文件路径可能解析为相同的内容,但指向不同的文件。不要在有安全意识的代码中使用它。

标签: c


【解决方案1】:

是 - 比较文件设备 ID 和 inode。根据<sys/stat.h> specification

st_ino 和 st_dev 字段共同唯一标识系统中的文件。

使用

int same_file(int fd1, int fd2) {
    struct stat stat1, stat2;
    if(fstat(fd1, &stat1) < 0) return -1;
    if(fstat(fd2, &stat2) < 0) return -1;
    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
}

【讨论】:

  • 虽然只是多出几行,但确实需要额外的标题。你能想到更快的方法吗?
  • #include &lt;sys/stat.h&gt; 有那么大吗?
  • 更快?你希望它快,还是你希望它是正确的?
  • 输入时间比执行时间更快。应该澄清一下。
  • 打字时间从来不是问题;开发时间(考虑问题解决方案、咨询参考资料等)和调试时间(修复不完善的解决方案中的错误、修复打字错误)是。永远不要试图减少打字时间并冒着增加开发或调试时间的风险;这样做不值得。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多