有没有办法让子目录的总大小具有递归性?
例如:
Dir1
-- FileA.txt (90)
-- SubDir2 (4096)
---- FileB.txt (100)
---- FileC.txt (400)
当我试图获得SubDir2的大小时,它给了我4186.我希望得到的预期答案是4596.
我的程序计算FileA的大小而不是FileB和FileC。如何计算FileB和FileC?
首先,我必须使用这些标题:
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
然后,我使这个函数递归地调用它:
static DIR *dir;
void goDir(char* argv[])
{
struct dirent *dit;
struct stat st;
int size = 0;
static int total_size = 0;
char filePath[NAME_MAX];
while ((dit = readdir(dir)) != NULL)
{
sprintf(filePath, "%s/%s", argv[1], dit->d_name); // To show correctly the size and name of files
lstat(filePath, &st);
// To skip . and ..
if ( (strcmp(dit->d_name, ".") == 0) || (strcmp(dit->d_name, "..") == 0) ) continue;
size = st.st_size;
if(S_ISDIR(st.st_mode))
{
goDir(argv); // For Recursivity
total_size += size;
printf("DIR\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %d\t", total_size);
printf("%s\n", dit->d_name);
}
else
{
total_size += size;
printf("FILES\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %d\t", size);
printf("%s\n", dit->d_name);
}
}
}
然后,我的主要计划:
int main (int argc, char *argv[])
{
if ( argc != 2 ) {
printf("Usage: Program <Directory>\n");
return 1;
}
if ((dir = opendir(argv[1])) == NULL) return 1;
goDir(argv);
closedir(dir);
return 0;
}
答案 0 :(得分:2)
您的goDir()
函数永远不会打开新目录,或者在完成后关闭目录。这将导致问题 - 基本上,您不会遍历目录层次结构。
您需要在dir
函数中设置static
个本地(非goDir()
)变量;你会打开和关闭目录;而不是传递argv
,你将传递目录名等。
当您处于此状态时,您应该更改goDir()
以返回找到的尺寸,并丢失static
变量total_size
。
这段代码看似半合理:
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#ifndef NAME_MAX
#define NAME_MAX 1024
#endif
static long goDir(char *dirname)
{
DIR *dir = opendir(dirname);
if (dir == 0)
return 0;
struct dirent *dit;
struct stat st;
long size = 0;
long total_size = 0;
char filePath[NAME_MAX];
while ((dit = readdir(dir)) != NULL)
{
if ( (strcmp(dit->d_name, ".") == 0) || (strcmp(dit->d_name, "..") == 0) )
continue;
sprintf(filePath, "%s/%s", dirname, dit->d_name);
if (lstat(filePath, &st) != 0)
continue;
size = st.st_size;
if (S_ISDIR(st.st_mode))
{
long dir_size = goDir(filePath) + size;
printf("DIR\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %ld\t", dir_size);
printf("%s\n", filePath);
total_size += dir_size;
}
else
{
total_size += size;
printf("FILES\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %ld\t", size);
printf("%s\n", filePath);
}
}
return total_size;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s <Directory>\n", argv[0]);
return 1;
}
long size = goDir(argv[1]);
printf("Total size: %ld\n", size);
return 0;
}
它编译并运行。它没有给出与du -k
相同的答案,主要是因为它没有将文件大小四舍五入到整数个磁盘块。您需要查看st_blksize
中的st_blocks
和/或struct stat
才能获取该信息。
答案 1 :(得分:0)
您必须使用哈希表来跟踪inode的出现次数。这样他们就不会被计算两次了。