我想通过一个C程序来获得在Linux中特定目录的确切大小。 我尝试使用的statfs(路径,结构的statfs&),但它没有给出确切大小。 我也试图与统计(),但它返回的尺寸为4096的任何目录!
请给我建议,通过它我可以得到目录的确切大小就像我们后“杜-SH dirPath”命令获取的方式。
此外,我不通过系统想用杜()。
提前致谢。
我想通过一个C程序来获得在Linux中特定目录的确切大小。 我尝试使用的statfs(路径,结构的statfs&),但它没有给出确切大小。 我也试图与统计(),但它返回的尺寸为4096的任何目录!
请给我建议,通过它我可以得到目录的确切大小就像我们后“杜-SH dirPath”命令获取的方式。
此外,我不通过系统想用杜()。
提前致谢。
典型的解决方案
如果你想有一个目录,在时尚类似于杜的大小,创建一个递归函数。 这是可能的迭代解决问题,但解决方案适合于递归。
信息
这里是一个链接,让你开始:
http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Prsize/lecture.html
搜索
谷歌搜索与“统计C程序递归目录大小”
例
直接从吉姆·普朗克网站,作为一个例子让你开始。
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
main()
{
DIR *d;
struct dirent *de;
struct stat buf;
int exists;
int total_size;
d = opendir(".");
if (d == NULL) {
perror("prsize");
exit(1);
}
total_size = 0;
for (de = readdir(d); de != NULL; de = readdir(d)) {
exists = stat(de->d_name, &buf);
if (exists < 0) {
fprintf(stderr, "Couldn't stat %s\n", de->d_name);
} else {
total_size += buf.st_size;
}
}
closedir(d);
printf("%d\n", total_size);
}
你需要STAT()中的所有文件在当前目录和子目录,并把它们加起来。
请考虑使用递归算法这一点。
如果你不希望使用'system'
,而是确定使用'pipe'
, 'fork'
, 'execlp'
和'du'
,你可以建立一个管道,一个新的进程,重定向'STDOUT'
孩子在管,EXEC 'du'
的孩子,并读取结果父。 样品代码将是:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
int pfd[2], n;
char str[1000];
if (pipe(pfd) < 0) {
printf("Oups, pipe failed. Exiting\n");
exit(-1);
}
n = fork();
if (n < 0) {
printf("Oups, fork failed. Exiting\n");
exit(-2);
} else if (n == 0) {
close(pfd[0]);
dup2(pfd[1], 1);
close(pfd[1]);
execlp("du", "du", "-sh", "/tmp", (char *) 0);
printf("Oups, execlp failed. Exiting\n"); /* This will be read by the parent. */
exit(-1); /* To avoid problem if execlp fails, especially if in a loop. */
} else {
close(pfd[1]);
n = read(pfd[0], str, 1000); /* Should be done in a loop until read return 0, but I am lazy. */
str[n] = '\0';
close(pfd[0]);
wait(&n); /* To avoid the zombie process. */
if (n == 0) {
printf("%s", str);
} else {
printf("Oups, du or execlp failed.\n");
}
}
}
我猜的解决方案可能是为那些谁仍可能会遇到的问题是有用的。
下面是被写入模仿Linux的功能du
项目。 它递归遍历所有目录,并增加了文件大小。
请注意 ,这个功能仍然是不完整的,因为它不正确的行为的硬链接。 每个人都应该添加一个容器来存储文件描述符指向同一个inode的实体并用它来摆脱非常同一文件的多个计数。 lstat()
是用来处理符号链接(也称为软链接), 硬链接是一个问题在这里 。
size_t countDiskUsage(const char* pathname)
{
if (pathname == NULL) {
printf("Erorr: pathname is NULL\n");
}
struct stat stats;
if (lstat(pathname, &stats) == 0) {
if (S_ISREG(stats.st_mode)){
return stats.st_size;
}
} else {
perror("lstat\n");
}
DIR* dir = opendir(pathname);
if (dir == NULL) {
perror("Error");
return 0;
}
struct dirent *dirEntry;
size_t totalSize = 4096;
for (dirEntry = readdir(dir); dirEntry != NULL; dirEntry = readdir(dir)) {
long pathLength = sizeof(char) * (strlen(pathname) + strlen(dirEntry->d_name) + 2);
char* name = (char*)malloc(pathLength);
strcpy(name, pathname);
strcpy(name + strlen(pathname), "/");
strcpy(name + strlen(pathname) + 1, dirEntry->d_name);
if (dirEntry->d_type == DT_DIR) {
if (strcmp(dirEntry->d_name, ".") != 0 && strcmp(dirEntry->d_name, "..") != 0) {
totalSize += countDiskUsage(name);
}
} else {
int status = lstat(name, &stats);
if (status == 0) {
totalSize += stats.st_size;
} else {
perror("lstat\n");
}
}
free(name);
}
closedir(dir);
return totalSize;
}