C-尝试在目录和所有子目录中打印字节中的总空间



我当前正在尝试制作一个C程序,该程序在给定目录的字节中计算总文件大小,包括目录本身,所有文件,以及所有SUB中的所有文件和目录 - 目录。本质上,我被要求将du -b替换为命令。

我以为我有一个工作解决方案,但是在第一个目录之后,该程序认为所有条目都更深的是目录,即使它们只是常规文件。这包括当我给它一个直接深度深度的目录时,通过给它输入./Directory1而不是.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
int du_function(char direc[]) {
    int total = 0;
    char str[100];
    strcpy(str, direc);
    struct stat sfile;
    struct dirent *de;
    DIR *dr = opendir(direc);
    if (dr == NULL) {
        printf("Could not open directoryn");
        return 0;
    }
    while ((de = readdir(dr)) != NULL) {
        printf("%sn", de->d_name);
        stat(de->d_name, &sfile);
        if (S_ISDIR(sfile.st_mode) && strcmp(de->d_name, ".") != 0 &&
            strcmp(de->d_name, "..") != 0) {
            strcat(str, "/");
            strcat(str, de->d_name);
            printf("This is a directory called %sn", str);
            total = total + du_function(str);
            strcpy(str, direc);
        }
        if (S_ISREG(sfile.st_mode) || strcmp(de->d_name, ".") == 0) {
            printf("Size in bytes = %ldn", sfile.st_size);
            total = total + sfile.st_size;
            printf("The total is %d bytes so far.n", total);
        }
    }
    printf("The total is %d bytes.n", total);
    closedir(dr);
    return total;
}
int main(int argc, char *argv[]) {
    if (argc < 2) {
        char cwd[1] = ".";
        du_function(cwd);
    } else
        du_function(argv[1]);
    return 0;
}

我在这里的机智结尾,尝试了各种解决方案,但是出于某种原因,S_ISDIR必须将事物识别为没有的目录(或更有可能从我那里接收错误的输入。)

char cwd[1] = ".";太小,对于 string 。没有房间 null字符

使用[],让编译器确定 String的所需尺寸

char cwd[] = ".";

stat()调用基于本地名称,而不是完整的路径。

#if 0
    stat(de->d_name, &sfile);
#else
    char buf[500];
    snprintf(buf, sizeof buf, "%s/%s", direc, de->d_name);
    stat(buf, &sfile);
#endif

(已删除)@pskocik

中的类似发现

也许还有其他问题。

就像您构造递归调用的路径一样,您必须使用stat系统调用的领先目录构造文件名。您的程序仅适用于当前目录中的文件。

修复程序的有效方法是将足够大的缓冲区传递给递归功能,并逐步构建路径并逐步固定到位:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
long int du_function(char path[], size_t size) {
    size_t len = strlen(path);
    long int total = 0;
    struct stat sfile;
    struct dirent *de;
    DIR *dr = opendir(path);
    if (dr == NULL) {
        printf("Could not open directory %sn", path);
        return 0;
    }
    while ((de = readdir(dr)) != NULL) {
        if (strcmp(de->d_name, "..") == 0)
            continue;
        //printf("%sn", de->d_name);
        if (snprintf(path + len, size - len, "/%s", de->d_name) > (int)(size - len)) {
            path[len] = '';
            printf("Path too long: %s/%sn", path, de->d_name);
            continue;
        }
        stat(path, &sfile);
        if (S_ISDIR(sfile.st_mode) && strcmp(de->d_name, ".") != 0) {
            //printf("This is a directory called %sn", path);
            total = total + du_function(path, size);
        } else
        if (S_ISREG(sfile.st_mode) || strcmp(de->d_name, ".") == 0) {
            //printf("Size in bytes = %ldn", (long)sfile.st_size);
            total = total + sfile.st_size;
            //printf("The total is %ld bytes so far.n", total);
        }
    }
    path[len] = '';
    printf("%ldt%sn", total, path);
    closedir(dr);
    return total;
}
int main(int argc, char *argv[]) {
    char path[1024] = ".";
    if (argc > 1) {
        strcpy(path, argv[1]);
    }
    du_function(path, sizeof path);
    return 0;
}

最新更新