Вот более подробный ответ для получения размера каталога. Его результаты совпадают с результатами утилиты "du" (Disk Usage).
При этом учитывается, что Linux считает, что сама запись каталога имеет размер. Он правильно обрабатывает символьные ссылки / ярлыки как в Linux, так и в Windows (а не игнорирует их!). Это также позволяет пользовательскому интерфейсу «дышать» более логичным образом, чем предполагать, что новый обход каталога - это точка, в которой можно «отдохнуть» на мгновение.
#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 );
}