C++ 如何在目录遍历中获得文件大小?
当我使用递归查看每个文件时,如何获得文件的大小? 我得到了下一个错误: project.exe已退出,代码为-1073741819C++ 如何在目录遍历中获得文件大小?,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
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 );
}