当我使用递归来查看每个文件时,如何获取文件的大小? 我收到了下一个错误:
project.exe退出,代码为-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;
}
答案 0 :(得分:8)
首先清理一下代码。
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;
}
如果你想保持ui被动,在一个单独的线程中进行计算,在每个文件中调用processEvent()是一个负担。 您还应该使用quint64(unsigned long long)来处理大文件(&gt; 2Go) 但是,目前还不清楚崩溃的位置。
答案 1 :(得分:1)
改变这个:
if(fileInfo.isDir())
{
sizex += this->get_dir_size(fileInfo.path());
QApplication::processEvents();
}
到
if(fileInfo.isDir())
{
sizex += dir_size(fileInfo.path()); //call recursively!
QApplication::processEvents();
}
你为什么打电话给get_dir_size()
- 不管它是什么?如果要以递归方式计算大小,则应调用dir_size()
。
答案 2 :(得分:1)
崩溃是因为你一次又一次递归地评估同一个文件夹。
语句sizex += this->dir_size(fileInfo.path());
以相同的文件夹名称递归调用相同的函数。
所以你的堆栈会不断增长并最终会内存不足。
fileInfo.path()
提供相同的(父)文件夹。
fileInfo.filePath()
为文件名提供路径
将其更改为sizex += this->dir_size(fileInfo.filePath());
,这应该解决它
答案 3 :(得分:0)
这是获取目录大小的更为开发的答案。其结果与实用程序“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 );
}