【问题标题】:Walk Directory recursively issueWalk Directory 递归问题
【发布时间】:2012-10-01 01:17:47
【问题描述】:

我正在尝试递归遍历目录并修改其内容,应该对所有文件和子目录的文件进行修改。

void EncryptMountedFolder(QString DirPath)
{
        QStringList listFile;
        QStringList listDir;
        int r=0;
    if(WalkDir(DirPath,listFile,listDir))
     {

        foreach (QString filePath, listFile)
        {
        //modif of file with filePath as path
        }

        foreach(QString subdirPath, listDir)
        {
            EncryptMountedFolder(subdirPath);
        }

      }
      else qDebug()<<"can not find "<<DirPath<<"or it is not folder path ";

}

WalkDir函数:

bool WalkDir(QString DirPath, QStringList &FList, QStringList &DList)
{
    QString p=QDir::fromNativeSeparators(DirPath);
    QDir dir( p );
    if(dir.exists())
    {           
          dir.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks );
          const QFileInfoList fileinfolist = dir.entryInfoList();

          foreach(const QFileInfo& fi,fileinfolist)
              if(fi.baseName() != "")
              {
                if( fi.isDir() && fi.isReadable() )
                 DList=DList << fi.absoluteFilePath() ;
                 else
                    FList= FList<< fi.absoluteFilePath();
              }              
        return true;
    }
    else
        {    qDebug()<<"not valid dir path or doesn't exist"<<DirPath ;
             return false;
         }    
}

所有子目录下的文件都按我的意愿进行了修改,但它崩溃了,我得到:Critical error detected c0000374 指向Q_OUTOFLINE_TEMPLATE void QList&lt;T&gt;::free(QListData::Data *data) 函数行中的qlist.h qFree(data);

谁能找出我想念的东西?

提前致谢。

【问题讨论】:

  • 我在 Linux 机器上执行了您粘贴的代码的 sn-p(将目录设置为走到中等大小的目录树:3 级深度,数百个文件),没有任何错误。因此,这可能特定于您用于加密文件的任何逻辑,或者如果您尝试扫描的目录树超过一定大小,则会出现错误。
  • 我认为您对步行的实施很可能是问题的根源。这是不必要的复杂。此外,使用传递给函数的参数作为返回值也不是一个好习惯:WalkDir(QString DirPath, QStringList &FList, QStringList &DList) 这很容易出错,而且它不能生成易于测试和维护的代码。
  • 虽然值得尝试调试此问题并了解问题所在,但我也建议您重新设计实现。您尝试实现的内容有 2 个不同的活动:(1. 目录遍历,2. 对单个文件进行处理以对其进行加密)。这些中的每一个都可以在单个函数中实现。看我的回答。

标签: c++ directory qt-creator subdirectory qlist


【解决方案1】:

根据我上一条评论,这是我简化步行功能的建议(基于this):

void walk( const QString& dirname )
{
  QDir dir( dirname );
  dir.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks );

  const QFileInfoList fileinfolist = dir.entryInfoList();
  foreach( const QFileInfo& fi,fileinfolist ) {
    if( fi.baseName() == "." || fi.baseName() == ".."  || fi.baseName() == "" ) {
      continue;
    }
    if( fi.isDir() && fi.isReadable() ) {
      // This is the conditional for recursion
      walk( fi.absoluteFilePath() );
    }
    else {
      // This is where you might call your encrypting function
      qDebug() << "Encrypting file: " << fi.absoluteFilePath();
      encrypt( fi.absoluteFilePath() );
    }
  }
}

您还可以通过将加密函数作为回调传递给 walk() 来使其更通用。这样您就可以将其重复用于您可能需要应用的其他类型的处理。

另外,如果您热衷于测试您的代码,您可能会注意到我之前的建议是不可单元测试的:对于易于测试的方法,它应该具有非依赖的输入和输出,并且您的测试将根据预期值检查输出。

所以这是一个返回从给定目录树中收集的所有文件列表的版本:

QStringList walk( const QString& dirname )
{
  QDir dir( dirname );
  dir.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks );

  const QFileInfoList fileinfolist = dir.entryInfoList();
  QStringList collectedFileList;
  foreach( const QFileInfo& fi,fileinfolist ) {

    if( fi.baseName() == "." || fi.baseName() == ".."  || fi.baseName() == "" ) {
      continue;
    }

    if( fi.isDir() && fi.isReadable() ) {
      collectedFileList << walk( fi.absoluteFilePath() );
    }
    else {
      collectedFileList << fi.absoluteFilePath();
    }
  }
  return collectedFileList;
}

现在您可以添加第三种方法来循环文件并加密它们:

void encryptDirectoryTree( const QString& dirname )
{
     QStringList filesInDir = walk( dirname );
     foreach( const QString& filePath, filesInDir ) {
        encrypt( filePath );
     }
}

【讨论】:

  • 真的很感谢您的帮助和您的时间谢谢@ylabidi。实际上,在看到您的建议之前,我重新测试了我的代码,并在我的加密算法实现中发现了处理 char* 和 strcpy 的源错误,所以我暂时修复了它,并重新实现了一种不同的方法,当用户加密或解密文件时需求,但现在我完全相信你的第二种方法,我会测试它,看看它是否更有效,再次感谢你。
猜你喜欢
  • 2016-02-01
  • 2021-09-07
  • 2011-12-10
  • 2011-08-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多