I am trying to walk a directory recursively and modify its contents,that modification should be done for all files and files of sub directories.
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
function:
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;
}
}
Files under all sub directories were modified as I want, but it crashes and I get: Critical error detected c0000374
that point me to qlist.h
in Q_OUTOFLINE_TEMPLATE void QList<T>::free(QListData::Data *data)
function line qFree(data);
Can anyone find out what I miss?
Thanks in advance.
As per my last comment, this is my suggestion to simplify the walking function (based on 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() );
}
}
}
You can also make it more generic by passing the encrypting function as a callback to walk(). So that you can reuse it for other types of processing you might need to apply.
Also if you're keen on testing your code, you might notice that my previous suggestion, is not unit-testable: for a method to be easily testable, it should have non-dependent input and output, and your test would check the output against the expected value.
So here is a version that returns the list of all files collected from the given directory tree:
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;
}
And now you can add a third method to loop over the files and encrypt them:
void encryptDirectoryTree( const QString& dirname )
{
QStringList filesInDir = walk( dirname );
foreach( const QString& filePath, filesInDir ) {
encrypt( filePath );
}
}