Reputation: 1960
How can I get the size of a file when I am using recursion to look at each file? I'm getting the next error:
project.exe exited with code -1073741819
int dir_size(const QString _wantedDirPath)
{
long int sizex = 0;
QFileInfo str_info(_wantedDirPath);
if (str_info.isDir())
{
QDir dir(_wantedDirPath);
QStringList ext_list;
dir.setFilter(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList();
for(int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
if ((fileInfo.fileName() != ".") && (fileInfo.fileName() != ".."))
{
sizex += (fileInfo.isDir()) ? this->dir_size(fileInfo.path()) : fileInfo.size():
QApplication::processEvents();
}
}
}
return sizex;
}
Upvotes: 7
Views: 5404
Reputation: 11048
Here's a more developed answer for getting a directory's size. Its results match those of the utility "du" (Disk Usage).
This takes into account that Linux considers the directory entry itself to have size. It handles symlink/shortcuts correctly in both Linux and Windows (rather than ignoring them!). This also allows the ui "breathe" in a more logical manner than assuming a new directory traversal is the point at which to "rest" for a moment.
#ifdef Q_OS_WIN32
#include <sys/stat.h>
long getStdFileSize( const std::string &filename )
{
struct stat stat_buf;
int rc = stat( filename.c_str(), &stat_buf );
return rc == 0 ? stat_buf.st_size : -1;
}
#endif
// designed to match the results of the standard
// cross platform utility "du" (Disk Usage)
// compare to du -b [path]
quint64 diskUsage( const QString &absPath, int &itemCount )
{
static const int UI_REFRESH_FREQ_ITEMS_TRAVERSED( 100 );
QFileInfo parentInfo( absPath );
if( parentInfo.exists() ) itemCount++;
quint64 totalBytes =
parentInfo.isSymLink() ?
// handle symlink size correctly
#ifdef Q_OS_WIN32
getStdFileSize( absPath.toStdString() )
#else
parentInfo.symLinkTarget().length()
#endif
: parentInfo.size();
if( parentInfo.isDir() )
{
QFileInfoList childInfoList = QDir( absPath ).entryInfoList(
QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot );
foreach( const QFileInfo &childInfo, childInfoList )
{
totalBytes += diskUsage(
childInfo.absoluteFilePath(), itemCount );
// prevent ui lockup, as this can potentially take a long time
if( (itemCount % UI_REFRESH_FREQ_ITEMS_TRAVERSED)==0 )
QGuiApplication::processEvents();
}
}
return totalBytes;
}
// convenience overload
quint64 diskUsage( const QString &absPath )
{
int itemCount=0;
return diskUsage( absPath, itemCount );
}
Upvotes: 0
Reputation: 916
Start by cleaning your code a bit.
quint64 dir_size(const QString & str)
{
quint64 sizex = 0;
QFileInfo str_info(str);
if (str_info.isDir())
{
QDir dir(str);
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
for (int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
if(fileInfo.isDir())
{
sizex += dir_size(fileInfo.absoluteFilePath());
}
else
sizex += fileInfo.size();
}
}
return sizex;
}
If you want to keep the ui reactive, do the calcul in a separate thread, call processEvent() at each file is a burden. You should also use quint64 ( unsigned long long ) to handle big files ( > 2Go ) But, it's not clear where the crash is.
Upvotes: 8
Reputation: 10473
Its crashing because you are recursively evaluating the same folder again and again.
The statement sizex += this->dir_size(fileInfo.path());
calls the same function recursively with the same folder name.
So your stack keeps growing and eventually out of memory.
fileInfo.path()
gives the same (parent) folder.
fileInfo.filePath()
gives the filename with the path
Change it to sizex += this->dir_size(fileInfo.filePath());
and that should fix it
Upvotes: 1
Reputation: 361254
Change this:
if(fileInfo.isDir())
{
sizex += this->get_dir_size(fileInfo.path());
QApplication::processEvents();
}
to
if(fileInfo.isDir())
{
sizex += dir_size(fileInfo.path()); //call recursively!
QApplication::processEvents();
}
Why do you call get_dir_size()
- whatever it is? You should call dir_size()
if you want to compute the size recursively.
Upvotes: 1