诊断QDir :: rmdir失败

4

我正在使用以下代码在Linux上删除空文件夹:

bool removeFolder (const QString& path)
{
   QDir dir(path);
   assert(dir.exists());
   return dir.rmdir(".");
}

由于某种原因,QDir::rmdir有时会返回false(对于特定的文件夹,但这些文件夹似乎没有任何问题)。如果我随后使用来自<unistd.h>::rmdir来删除相同的文件夹,则成功。

我如何知道QDir::rmdir失败的原因?

到目前为止,在Windows上从未发生过这种情况,QDir::rmdir正常工作。


检查您的目录是否真的为空。没有隐藏文件?临时文件?类似于偏离 .nfs????? 文件的东西? - Greenflow
@Greenflow:它是完全空的。我不相信rmdir也容忍非空目录,而且它可以正常工作。我还有assert(dir.entryList(QDir::NoDotAndDotDot | QDir::Hidden | QDir::System).isEmpty()),但它从未触发过。 - Violet Giraffe
好的,我考虑过在删除文件和您的目录之间存在竞争条件,但是您的断言使这种情况不太可能发生。 - Greenflow
当你执行dir.rmdir(path);dir.rmdir(".");时,有什么区别吗?我不知道为什么会有区别。但是我也不知道为什么它会失败。 - Greenflow
@VioletGiraffe,我知道这是一个Unix系统函数,但你是从QDir对象中调用它的,该对象只返回true或false,没有失败的原因。如果从QProcess中调用,你应该能够获取失败的错误消息。我并不建议你直接使用QProcess,而是使用它来查看是什么导致了删除失败。 - TheDarkKnight
显示剩余5条评论
3个回答

2

确认:在Windows上运行正常,在Linux上失败。

在阅读 <unistd> 中的 "rmdir" 文档时,这里是链接:https://pubs.opengroup.org/onlinepubs/007904875/functions/rmdir.html。其中提到 "如果 path 参数引用的路径最后一部分为句点或双句点,则 rmdir() 将失败。"。所以可能发生的情况是 QDir::rmdir() 在 Linux 上调用了 unistd 的 rmdir() 函数,而该函数因 "." 而失败。

我尝试只使用完整的绝对路径 (QDir::rmdir(absolutePath)),它可以工作;但是,我认为使用 unistd 的 rmdir() 函数比使用 QDir::rmdir() 没有什么意义,所以我将坚持使用 unistd 的 rmdir() 函数。

注意:QDir::removeRecursively() 是另一回事:它似乎可以正常工作,并且比通过 opendir() 然后连续使用 readdir() (或 nftw(...FTW_DEPTH...) 这样的东西) 更方便。


使用Qt的目的是保持代码跨平台(一次编写,到处运行)。 - Violet Giraffe
@VioletGiraffe <unistd> 是跨平台的。而且,如果一个函数在 Windows 上可以工作,在 Linux 上却因为相同的参数而失败,那么它就不是跨平台的。Qt 或其他“跨平台”工具包很棒,但只有在没有标准库替代方案时才应该使用它们作为最后的兼容性层。 - Gyll

1

我遇到了相同的问题,但是在Windows上,我无法使用QDir().rmdir(path);删除一个空目录。这发生在一些旧硬盘上,可能是古老的文件系统有问题。但我找到了一个解决方法:

QFile(path).setPermissions(QFile::WriteOther); // this works even for dirs
bool success = QDir().rmdir(path);

当然,如果删除不成功,您应该将权限恢复到原始值,但这是另一回事。

0

尝试使用这个:

dir.rmdir(dir.absolutePath())

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