在读取/写入/追加模式下打开QFile后,是否可以检测到它的存在?

时间:2019-01-16 16:56:15

标签: c++ qt boost qfile

我想用随机选择的文件名向文件中写入一些文本,但想要求该文件尚不存在。在简单的QFile::exists检查和后面带有已检查名称的open之间存在竞争条件。

QFile打开文件时,确保该文件不存在的最佳方法是什么?使用boost::filesystem::create_directory时,与目录相同的内容可以很好地工作,因为它返回一个布尔值,该布尔值指示目录是否已存在。但是我看不到它对文件的工作方式。

1 个答案:

答案 0 :(得分:5)

我必须承认我从来没有亲自尝试过。

但是,我记得在文件I / O中防止竞争状况的通常方法是分别尝试并处理可能的错误情况。

因此,我查看了QFile::open()的功能并发现:

QIODevice::NewOnly

  

如果要打开的文件已经存在,则失败。仅当文件不存在时才创建并打开该文件。操作系统保证您是唯一创建和打开文件的人。请注意,此模式暗含WriteOnly,并允许将其与ReadWrite结合使用。该标志当前仅影响QFile。其他类将来可能会使用此标志,但是在此之前,将此标志与QFile以外的任何其他类一起使用可能会导致未定义的行为。 (自Qt 5.11起)


我刚刚意识到(除了我们高效的Qt 5.9安装),我安装了一个较新的版本,用于私人摆弄。

因此,我提供了一些示例来进行验证:

#include <QtWidgets>

int main()
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  for (int i = 1; i <= 2; ++i) {
    qDebug() << "Iteration" << i;
    QFile qFile("test.txt");
    if (!qFile.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
      qDebug() << "qFile.open failed! Error code" << qFile.error();
    }
    qFile.write("test");
    qFile.close();
  }
  return 0;
}

输出:

Qt Version: 5.11.2
Iteration 1
Iteration 2
qFile.open failed! Error code 5
QIODevice::write (QFile, "test.txt"): device not open

我仍然不太确定如何准确地确定它是否由于现有文件(而不是由于其他任何原因)而失败。就我而言,但可以肯定吗?

(错误代码5就是QFileDevice::OpenError。)