我想递归地计算目录(path)的大小。在我当前的代码中,我有一个函数来识别它是目录还是文件,如果它是目录,它会调用子目录(file)的函数,如果它是文件,它会添加到totalSize变量中。但是,我当前的代码没有返回任何意味着某个地方有错误的信息。下面是我的代码-
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
void getsize(const char *path,int* totalSize);
int main()
{
int total = 0;
char path [] = "C:\\Users\\abbas\\Desktop\\Leetcode airplane";
getsize(path,&total);
printf("%d",total);
return total;
}
void getsize(const char *path,int* totalSize)
{
struct dirent *pDirent;
struct stat buf;
struct stat info;
DIR *pDir;
int exists;
char str[100];
pDir = opendir (path);
while ((pDirent = readdir(pDir)) != NULL)
{
stat(pDirent->d_name,&info);
if(S_ISDIR(info.st_mode))
{
strcpy(str,path);
strcat(str,"/");
strcat(str,pDirent->d_name);
getsize(str,totalSize);
}
else
{
strcpy(str,path);
strcat(str,"/");
strcat(str,pDirent->d_name);
exists = stat(str,&buf);
if (exists < 0)
{
continue;
}
else
{
(*totalSize) += buf.st_size;
}
}
}
closedir(pDir);
}
3条答案
按热度按时间pkln4tw61#
1.包含字符串. h。
1.任意固定大小的
str[100]
是有问题的。如果你在Linux上使用linux/limits. h并使用str[PATH_MAX]
或更好的pathconf(path, _PC_NAME_MAX)
。在任何情况下,你都应该确保缓冲区足够大(例如使用snprintf()
),或者动态分配缓冲区。1.您需要排除
.
和..
,否则将导致无限循环(path/../path/..
)。stat(pDirent->d_name,&info)
失败,因为您需要stat()
path
/pDirect->d_name
,而不仅仅是pDirect->d_name
。1.(未修复)可能是
snprintf(path2, sizeof path2, "%s%s%s", path, PATH_SEP, pDirenv->d_name)
,而不是strcpy()
和strcat()
?1.检查函数的返回值,否则你就是在浪费时间。
1.没有必要在同一路径上执行两个
stat()
调用,所以只需使用(*totalSize) += buf.st_size;
。1.(未修复)在Windows上,请考虑将_stat64()与结构体__stat64(@AndrewHenle)的地址一起使用。
1.我假设你只需要文件的大小。
1.(未修复)如果
getsize()
返回大小,而不是使用int *totalSize
输出参数,则会更自然。1.(未修复)请考虑使用
nftw()
(或较旧的ftw()
)遍历树。请注意,程序现在接受路径通过命令行进行测试.
和示例测试:
oxiaedzo2#
我认为你的代码的主要错误在于递归逻辑。
引用《C编程语言》第183页:
每个目录始终包含其自身的条目(称为.“")和其父目录的条目(..”");这些必须被跳过,否则程序将永远循环。
因此,您可以尝试在
while
循环的开头添加以下if
测试:尽管如此,可能还有其他错误,但我认为这一个是最重要的。
13z8s7eq3#
练习安全编码。
低于风险缓冲区溢出。
编码完成后,
然后代码很容易错误地在
"."
和".."
上递归,导致OP自我发现一个关键问题。这有助于更快的代码生产和更有弹性的代码。节省OP时间。