【问题标题】:how to find out if two filenames refer to the same file如何找出两个文件名是否引用同一个文件
【发布时间】:2018-03-14 18:52:01
【问题描述】:

这是一个关于如何使用Qt的问题。 我有两条路径,让我们说“c:\users\herbie\stuff\file1.txt”和“c:\users\HERBIE\stuff\file1.txt”。

我想写一个方法会告诉我这两个路径是否引用同一个文件。这个方法应该可以在windows和linux下工作。因此,我认为可以使用 Qt 类来解决这个问题,但我还没有找到如何去做。

Windows 不区分大小写,因此在 Windows 上这两个指的是同一个文件。在 linux 上,它们会引用不同的文件。

有人知道怎么做吗?字符串比较不起作用(因为区分大小写),Qt 类(如 QFileInfo、QDir 等)总是返回构造函数设置给它们的路径,而不是系统上实际存在的名称。

感谢任何帮助!

【问题讨论】:

  • 为什么字符串比较不起作用? std::string("HELLO") != std::string("hello")
  • 因为在忽略大小写的文件系统中,"HELLO.TXT""hello.txt" 是同一个文件。
  • 在linux上可以正常工作,因为目录“HELLO”与“hello”不同,但在windows上是同一个目录!

标签: c++ qt


【解决方案1】:

QFileInfo::operator== 定义为如果两个路径引用同一个文件,则返回 true,除非 (A) 一个是 Windows 8.3“短”名称,另一个是它的“长”名称或 (B) 当一个是到另一个的符号链接。此处不适用任何例外情况。

【讨论】:

  • 我查看了 Qt 源代码,QFileInfo::operator== 本质上只是比较了 canonicalFilePaths 和 QFileInfos,根据操作系统的不同,在 CaseSensitive 或 CaseInsensitive 模式下。这比使用boost 更好也更差,后者实际上深入到了 FS 的深处并比较了 iNode 数量。我也不明白为什么会有关于符号链接的评论,因为canonicalFilePath 声称无论如何都会删除所有符号链接。
【解决方案2】:

编辑

更好地查看boost::filesystem::equivalent :)

如果sf1 == sf2 和 p1 和 p2 解析到同一个文件系统实体,则返回 true,否则返回 false。

【讨论】:

  • @ededsh,你应该参考boost::filesystem::equivalent
  • 谢谢!我会看看它,虽然我可能不会仅仅为了解决这个烦人但小问题而包含 Boost
  • @user3010236 明白了。我只想说,尽管 Boost 库的声誉好坏参半,但这个库是 Boost 可移植性绝对值得麻烦的库。
【解决方案3】:

How do I get the correct case of a path? 提出了类似的问题。

Slomojo 的解决方案有点小题大做,但似乎没有办法解决。

没有简单的方法可以做到这一点,但你可以尝试做一个 QDir.entryList,然后对结果进行不区分大小写的搜索。 这将为您提供正确的文件名。然后你需要 获取该结果的absolutePath

这应该为您提供路径/文件名的保留大小写。

【讨论】:

  • 谢谢!但我想我会接受 Happy to use #ifdef WINDOWS 的建议。我曾希望避免这种情况,但它似乎仍然比 Slomojo 建议的解决方案快得多。
【解决方案4】:

您需要使用#ifdefs 编写特定于操作系统的代码。如果您在 Windows 上运行,请将路径转换为大写,然后进行比较。如果您在 Linux 上,请按原样进行比较。每个操作系统上都有一些您可以使用的预定义宏。

您可以使用此处的列表:http://sourceforge.net/p/predef/wiki/OperatingSystems/

这样,您的代码将如下所示:

#ifdef __WINDOWS__
// do case-insensitive compare
#else
// do case-sensitive compare 

【讨论】:

  • 但即便如此,/abc/../foo/foo 还是同一个文件。 /./././foo 也是如此。那么硬链接、重新绑定坐骑等呢?公平地说,OP 没有指定他们是否要检查相同的实际文件或相同的路径。
  • 如果我们在谈论规范文件路径,这将起作用。但是,它不适用于不必要地包含 ... 的路径。
  • 嗯,是的,但是 OP 的问题非常强调区分大小写的问题,所以我猜他已经想出了如何在这些情况下获得绝对路径。
  • 这几乎是 Qt 已经做的,所以你不需要。
  • 还要注意路径区分大小写不是操作系统的特性,而是卷文件系统的特性。例如,FAT32 不区分大小写,但 Linux ext 文件系统是。但话又说回来,NTFS 在设计上区分大小写,但 Windows 不允许您创建仅出于旧版软件兼容性而有所不同的文件名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2012-11-12
相关资源
最近更新 更多