qt与sqlite数据库同步文件的最佳方法

时间:2014-07-14 20:01:34

标签: database qt file filesystems

我正在寻找使用sqlite db同步某些目录中文件的最佳方法。

首先,我使用一个递归查找按扩展名筛选的文件的线程,并添加它们执行我的数据库。 接下来,我使用QFileSystemWatcher来观察文件是否发生变化并且运行良好。

问题在于,每次运行应用程序时,我都不知道文件是否已更改,因此我需要运行该线程,并且在执行期间(大约1分钟)需要100%的cpu(<1分钟)

那么我该如何改进这个算法呢? 感谢

此致 A993

编辑:

代码是一个递归函数,类似于我用来计算目录中文件的函数(也是这个函数需要100%的cpu)

int MediaScan_Thread::recursiveCount(QDir &dir)
{
    int i=dir.entryInfoList(_filters,QDir::Files).count();
    foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot))
     {
         QDir subdir(info.absoluteFilePath());
         i += recursiveCount(subdir);
     }

    return i;
}

我正在开发linux,但我会开发一个多平台应用程序。

1 个答案:

答案 0 :(得分:0)

我将迭代一个entryList()列表,递归目录并检查文件上的文件过滤器。没有一种简单的方法可以通过多个线程递归搜索文件列表。但是一旦你获得文件列表,就可以很容易地进行并行处理。

我将计数和文件列表的调用合并到I / O上的一次命中,因为没有任何理由这样做两次。此版本将跟踪查询的QStringList,以便稍后进行更多处理。

在递归函数上使用foreach可能会有问题,因为列表的副本已经生成,因此我切换到使用带迭代器的for循环。

特殊添加是模仿QDir nameFilters功能,因为entryList()接受一个fileFilters参数,它用于目录和文件(不是我们想要的)。

我省略的一个功能是递归深度限制,以避免永远搜索。

此代码示例已编译但未经过测试

    // declare in MediaScan_Thread and set them in constructor or wherever it needs to be:
    QVector<QRegExp>    _nameRegExps;
    QStringList         _filters;
    QDir::Filters       _dirFilters;

    // ....

    void    MediaScan_Thread::initFilterRegExp()
    {
        _nameRegExps.clear();
        for (int i = 0; i < _filters.size(); ++i)
        {
            _nameRegExps.append( QRegExp(_filters.at(i), (_dirFilters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard) );
        }
    }

    int MediaScan_Thread::recursiveCountAndMatchedFiles(QDir &dir, QStringList& matchedFiles )
    {
        int i = 0;
        QFileInfoList   lst = dir.entryInfoList( QStringList() , QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot );

        for ( auto itr = lst.begin(); itr != lst.end(); itr++ )
        {
            QFileInfo &info = (*itr);

            if (info.isDir())
                i += recursiveCountAndMatchedFiles( info.absoluteDir(), matchedFiles );
            else
            {
                QString fileName = info.absoluteFilePath();
                for (auto iter = _nameRegExps.constBegin(), end = _nameRegExps.constEnd();
                    iter != end; ++iter)
                {
                    if (iter->exactMatch(fileName)) {
                        i++;
                        matchedFiles << fileName;
                        break;
                    }
                }
            }
        }

        return i;
    }