将 QFile 正确存储在集合中

Posted

技术标签:

【中文标题】将 QFile 正确存储在集合中【英文标题】:Properly storing QFiles in a collection 【发布时间】:2016-04-03 21:44:42 【问题描述】:

在一个集合中存储多个 QFile 的最佳方式是什么?最好使用 QList、数组还是向量?

我想以 QFile 而不是 QFile* 的形式访问集合的元素。

我正在尝试读取 Qt 中的目录并将所有文件存储在一个集合中。然后将所有文件名打印到屏幕上。

我是如何阅读目录的:

QDirIterator it(p_dir, QStringList() << "*.wav", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext())

    // Put file into collection

目前我正在使用 QList 来存储 QFiles:

QList<QFile*> list;

我读到获取文件信息的最佳方法是使用 QFileInfo 类型。如何将 QFileInfo 文件设置为列表中的元素?

我想做这样的事情:

QFileInfo info;
QListIterator<QFile*> i(list);
while(i.hasNext()) 

    info.setFile(i);

但是上面给了我: 错误:没有用于调用 'QFileInfo::setFile(QListIterator&)' 的匹配函数 fi.setFile(i);

【问题讨论】:

看起来你想要的不是 QFile,而是一系列文件名,因此 QStringList 会做得很好 【参考方案1】:

请记住QFile 继承QObject,因此不可复制或移动。通常的做法是将指向此类对象的指针存储在容器中,而不是对象本身。至于使用哪个容器,其实并不重要,但QVector 会是最高效的。

QListIterator 是一个 Java 风格的迭代器。所以:

QListIterator::QListIterator(const QList&lt;T&gt; &amp; list)

构造一个遍历列表的迭代器。迭代器设置为 在列表的前面(第一项之前)。

迭代器不指向任何东西,如果你想得到实际的对象,使用i.next()给你一个QFile*,然后你必须取消引用,因为setFile()接受QFile &amp; ,而不是QFile *

【讨论】:

如果不需要同时访问,最好使用QFileInfoList,只在需要的时候打开一个QFile【参考方案2】:

QFile 不可复制。在 C++98 中,通常无法将其存储在容器中,除非容器支持就地构造。我不知道任何这样的 C++98 容器,虽然写一个不会那么难。

在 C++11 中,您可以使用任何不需要复制元素并支持放置的容器,例如std::list:

// https://github.com/KubaO/***n/tree/master/questions/qfile-list-36391586
#include <QtCore>
#include <list>

void populate(std::list<QFile> & files) 
   QDir dir(QCoreApplication::applicationDirPath());
   for (auto fileName : dir.entryList(QDir::Files)) 
      qDebug() << "adding file" << fileName;
      files.emplace_back(fileName);
   


void iterate(std::list<QFile> & files) 
   for (auto & file : files)
      if (file.open(QIODevice::ReadOnly)) 
         qDebug() << "successfully opened" << file.fileName();
      


int main(int argc, char ** argv) 
   QCoreApplication app(argc, argv);
   std::list<QFile> files;
   populate(files);
   iterate(files);

在我的系统上,当从 Qt Creator 运行时,输出是:

adding file "main.o"
adding file "Makefile"
adding file "qfile-list-36391586"
successfully opened "main.o"
successfully opened "Makefile"
successfully opened "qfile-list-36391586"

由于QFile是一个适当的类实现系统资源的RAII,文件将在main返回之前被files::~list自动关闭。

【讨论】:

【参考方案3】:

我目前正在根据某些标准/逻辑操作 QFileInfo..但如果我只是过滤所有复杂的逻辑,它会是这样的

QDir testDir("/home/mypath/to/dir");
QFileInfoList files = testDir.entryInfoList();    // #1. here you may use filters as I'm filtering based on a specific file extension
QFileInfoList myfiles;

for(int index = 0; index < files.size(); ++index)

    const QFileInfo& info = files.at(index);
    qDebug() << info.absoluteFilePath() << endl;   
   // #2. I've some sort of filters I used in #1 above that I compares here by utilizing info here, something like 
   //if (info.baseName().contains("anyPattern");
        myfiles.push_back(info);      
    
// Now you can view whatever you stored    
for (int vw_idx = 0; vw_idx < myfiles.size(); ++vw_idx)
 
   const QFileInfo& info = files.at(index);
   qDebug() << info.absoluteFilePath() << endl;     
   

【讨论】:

以上是关于将 QFile 正确存储在集合中的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将集合选择放在 form_tag 中?

如何跳过 QFile 的 N 行而不将它们临时存储在 QStrings 中?

如何在 Qhash 中存储 Qfile

如何正确地将 JArray 解析为字符串集合

在 QIODevice 子类中覆盖 readData 会返回不正确的结果

java关于集合框架,说法不正确的是( )