C++ 如何在目录遍历中获得文件大小?

C++ 如何在目录遍历中获得文件大小?,c++,qt,C++,Qt,当我使用递归查看每个文件时,如何获得文件的大小? 我得到了下一个错误: project.exe已退出,代码为-1073741819 int dir\u size(常量QString\u wantedDirPath) { 长整数sizex=0; QFileInfo str_info(_wantedDirPath); 如果(str_info.isDir()) { QDir dir(_wantedDirPath); QStringList外部列表; dir.setFilter(QDir::Files

当我使用递归查看每个文件时,如何获得文件的大小? 我得到了下一个错误:

project.exe已退出,代码为-1073741819

int dir\u size(常量QString\u wantedDirPath)
{
长整数sizex=0;
QFileInfo str_info(_wantedDirPath);
如果(str_info.isDir())
{
QDir dir(_wantedDirPath);
QStringList外部列表;
dir.setFilter(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks);
QFileInfoList=dir.entryInfoList();
对于(int i=0;i目录大小(fileInfo.path()):fileInfo.size():
QApplication::processEvents();
}
} 
} 
返回sizex;
}
更改此选项:

if(fileInfo.isDir())
{
     sizex += this->get_dir_size(fileInfo.path());
     QApplication::processEvents();
}


为什么要调用
get\u dir\u size()
-不管它是什么?如果要递归计算大小,应该调用
dir\u size()

首先清理一下代码

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;
} 
quint64目录大小(常量QString&str)
{
quint64 sizex=0;
QFileInfo str_info(str);
如果(str_info.isDir())
{
QDir-dir(str);
QFileInfoList list=dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::nodotanddot);
对于(int i=0;i
如果要保持ui的反应性,请在单独的线程中进行计算,在每个文件中调用processEvent()是一个负担。 您还应该使用quint64(unsigned long-long)来处理大文件(>2Go)
但是,还不清楚崩溃在哪里。

它崩溃了,因为您正在一次又一次地递归计算同一个文件夹。 语句
sizex+=this->dir_size(fileInfo.path())使用相同的文件夹名称递归调用相同的函数。
因此,堆栈不断增长,最终内存不足

fileInfo.path()
提供相同的(父)文件夹

fileInfo.filePath()
提供文件名和路径


将其更改为
sizex+=this->dir\u size(fileInfo.filePath()),这应该可以解决这个问题。

这里有一个更完善的答案来获取目录的大小。它的结果与实用程序“du”(磁盘使用)的结果相匹配

这考虑到Linux认为目录条目本身具有大小。它在Linux和Windows中都能正确处理符号链接/快捷方式(而不是忽略它们!)。这还允许ui以比假设新的目录遍历是“休息”片刻的点更符合逻辑的方式“呼吸”

#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 );
}
#ifdef Q#u OS#u WIN32
#包括
长getStdFileSize(常量std::字符串和文件名)
{
结构统计;
int rc=stat(filename.c_str(),&stat_buf);
返回rc==0?统计数据大小:-1;
}
#恩迪夫
//旨在与标准的结果相匹配
//跨平台实用程序“du”(磁盘使用)
//与du-b[path]进行比较
quint64磁盘使用率(常量QString和absPath、int和itemCount)
{
静态常量(100);
QFileInfo parentInfo(absPath);
如果(parentInfo.exists())itemCount++;
总共64字节=
parentInfo.isSymLink()?
//正确处理符号链接大小
#ifdef Q_OS_WIN32
getStdFileSize(absPath.tostString())
#否则
parentInfo.symLinkTarget().length()
#恩迪夫
:parentInfo.size();
if(parentInfo.isDir())
{
QFileInfoList childInfoList=QDir(absPath).entryInfoList(
QDir::Files | QDir::Dirs | QDir::Hidden | QDir::nodotanddot);
foreach(常量QFileInfo&childInfo,childInfoList)
{
totalBytes+=磁盘使用率(
childInfo.absoluteFilePath(),itemCount);
//防止ui锁定,因为这可能需要很长时间
if((itemCount%UI\u刷新\u频率\u遍历的项目)=0)
QGUI应用程序::processEvents();
}
}
返回totalBytes;
}
//便利超载
quint64磁盘使用率(常量QString和absPath)
{
int itemCount=0;
返回diskUsage(absPath、itemCount);
}

Q需要以更好的方式形成,它在哪里崩溃?为什么不将
QDir::NoDotAndDotDot
添加到QDir的过滤器中?那你就不应该去查那个。和。。因为这个过程是类的成员,所以我使用“this->”link@mcuw:
get\u dir\u size()
dir\u size()
不同。仔细阅读代码。不知何故,
filePath
也导致了堆栈溢出<代码>绝对文件路径
修复了它。
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;
} 
#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 );
}