【问题标题】:Display and read all files in directory显示和读取目录中的所有文件
【发布时间】:2014-05-21 00:55:42
【问题描述】:

我正在尝试打印目录中所有文件的文件名。但是,有些文件不显示或无法打开。

如果我重新启动程序,之前无法打开的文件实际上已经打开并显示出来了。 怎么回事?

这是我的代码:

 QDirIterator iterator(dir.absolutePath(), QDirIterator::Subdirectories);
       while (iterator.hasNext()) {
          iterator.next();



              QFile file(iterator.next());

               if ( file.open( QIODevice::ReadOnly ) ) {
                     qDebug() << QFileInfo(file).fileName() << endl;


               } else {
                   qDebug() << "Can't open " << QFileInfo(file).fileName() << endl;
               }
       }

【问题讨论】:

  • 当您收到来自open() 的错误时,file.error() 会告诉您什么?
  • 我得到5的输出
  • QFile::OpenError 5 The file could not be opened. 好吧,我想这不是很有帮助。您的程序的其他部分是否有可能以非共享模式打开该文件?
  • 为什么要把迭代器推进两次?!您将跳过每个第二个文件!只需删除iterator.next();
  • @RetiredNinja:我认为删除您的答案不是最好的主意。它会起作用,所以它很有用。它只是缺少一些解释并为其添加更多代码。我刚刚提到了这些,但这并不意味着我发现它没有用。我建议取消删除它,以便读者也可以看到。两个用户已经发现它很有用。 :)

标签: c++ qt qtcore qfile qdir


【解决方案1】:

这里有一个问题:

 iterator.next();
 QFile file(iterator.next());
 if ( file.open( QIODevice::ReadOnly ) ) {

您正试图在循环内将迭代器推进两次。这意味着您可能会遍历表示无效文件的最后一个元素,然后由于明显的原因而失败。

根据文件夹的内容,即它是否在下一次运行时略有变化,即添加或删除一个文件,此循环可能会在下一次“工作”,即它试图打开的所有文件都会被打开,但它仍会跳过其形式的文件。

正确的解决方法是从迭代中删除这一行:

iterator.next();

因此,为方便起见,您的整个代码将如下所示:

QDirIterator iterator(dir.absolutePath(), QDirIterator::Subdirectories);
while (iterator.hasNext()) {
    QFile file(iterator.next());
    if ( file.open( QIODevice::ReadOnly ) )
        qDebug() << "Opened:" << file.fileName() << endl;
    else
        qDebug() << "Can't open " << file.fileName() << file.errorString() << endl;
}

根据 cmets 至少要注意两点:

  • 在这种情况下,您可以使用the errorString() method 获取更多信息。

  • 您不需要构造 QFileInfo 来获取文件名。 QFile 对象already has a method for that.。问题是您正在递归地迭代,因此,您只打印出基本名称而不知道文件所在的位置。如果不同子目录中存在同名文件,也可以多次显示同一个文件名。

【讨论】:

  • 感谢您的回答!我使用了QFileInfo,因为我只想显示文件名而不是完整路径。
  • @MicroPenguin:这不是一个好主意。提供尽可能多的信息总是更好的选择。事实上,您可以在不同的子目录中不加区别地显示相同的名称!
  • 谢谢@Laszlo。您似乎对 Qt 非常了解。我刚刚开始学习如何使用该框架。
【解决方案2】:

为什么不使用 QDir::entryList?

来自 Qt 助手:

QStringList QDir::entryList (const QStringList & nameFilters, Filters filters = NoFilter, SortFlags sort = NoSort) const 返回目录中所有文件和目录的名称列表,根据之前使用 setNameFilters() 和 setFilter() 设置的名称和属性过滤器排序,并根据使用 setSorting() 设置的标志排序。

可以使用 nameFilters、filters 和 sort 参数覆盖名称过滤器、文件属性过滤器和排序规范。

如果目录不可读、不存在或没有符合规范的内容,则返回一个空列表。

另请参见 entryInfoList()、setNameFilters()、setSorting() 和 setFilter()。

【讨论】:

  • entryList 不是递归的,因此您需要自己进行递归。因此,正确的方法是 OP 正在使用的恕我直言。你似乎也没有指出这个问题。
猜你喜欢
  • 2014-11-10
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多