C 如何仅根据文件类型和大小比较多个文件

C 如何仅根据文件类型和大小比较多个文件,c,C,目标是按大小比较文件并过滤相同大小的文件。 为此,您需要将每个文件与每个文件进行比较。 但是,第一个循环不起作用,因此对第一个目录的搜索停留在第一个文件上 #include <dirent.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/stat.h> int main(int argc, char *v[]) { struct

目标是按大小比较文件并过滤相同大小的文件。 为此,您需要将每个文件与每个文件进行比较。 但是,第一个循环不起作用,因此对第一个目录的搜索停留在第一个文件上

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>

int main(int argc, char *v[]) {
    struct dirent *d_verzeichnis1;
    struct dirent *d_verzeichnis2;
    DIR *dir1;
    DIR *dir2;
    FILE *file = fopen(v[3], "W");
    dir1 = opendir(v[1]);
    dir2 = opendir(v[2]);
    struct stat filesize1;
    struct stat filesize2;

    while ((d_verzeichnis1 = readdir(dir1)) != NULL) {
        stat((d_verzeichnis1->d_name), &filesize1);
        while ((d_verzeichnis2 = readdir(dir2)) != NULL) {
            stat((d_verzeichnis2->d_name), &filesize2);
            if (filesize1.st_size == filesize2.st_size);
            {
                printf("%s und %s sind gleich\n", 
                       d_verzeichnis1->d_name, d_verzeichnis2->d_name);
            }
        }   
        d_verzeichnis1 = readdir(dir1); 
    }
}

您的代码中存在多个问题:

如果提供的参数少于3个,则应验证命令行上提供的参数的实际数量,以避免出现未定义的行为。 fopenv[3],W;使用无效的模式字符串,应使用w。目前尚不清楚该流指针的用途。 dir1和dir2未经测试:如果opendir失败,则有未定义的行为。 使用目录条目名调用stat,如果目录与当前目录不同,则该条目名不是文件的相对路径名。您应该根据目录名和条目名构造路径名。 如果filesize1.st_size==filesize2.st_size;有一个额外的;在行的末尾,导致以下块无条件执行。你应该使用K&R风格,在行尾加上{`以避免这种愚蠢的错误。 并行扫描的逻辑不正确:您应该重新打开或至少倒带第一个目录中每个条目的第二个目录,以允许对潜在匹配项进行完整扫描。 以下是更正的版本:

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

char *buildpath(char *dest, size_t size, const char *dir, const char *name) {
    size_t len = strlen(dir);
    const char *sep = "";

    if (len > 0 && dir[len - 1] != '/')
        sep = "/";

    if ((unsigned)snprintf(dest, size, "%s%s%s", dir, sep, name) < size)
        return dest;
    else
        return NULL;
}

int main(int argc, char *argv[]) {
    char path1[1024];
    char path2[1024];
    struct dirent *dp1;
    struct dirent *dp2;
    DIR *dir1;
    DIR *dir2;
    struct stat filesize1;
    struct stat filesize2;

    if (argc < 3) {
        fprintf(stderr, "missing argument\n");
        fprintf(stderr, "usage: cmpdir dir1 dir2\n");
        return 1;
    }

    dir1 = opendir(argv[1]);
    if (dir1 == NULL) {
        fprintf(stderr, "cannt open directory %s: %s\n", argv[1], strerror(errno));
        return 1;
    }
    dir2 = opendir(argv[2]);
    if (dir2 == NULL) {
        fprintf(stderr, "cannt open directory %s: %s\n", argv[2], strerror(errno));
        return 1;
    }
    while ((dp1 = readdir(dir1)) != NULL) {
        /* ignore . and .. entries */
        if (!strcmp(dp1->d_name, ".")
        ||  !strcmp(dp1->d_name, ".."))
            continue;
        if (!buildpath(path1, sizeof path1, argv[1], dp1->d_name)) {
            /* path too long */
            continue;
        }
        if (stat(path1, &filesize1)) {
            /* cannot stat entry */
            continue;
        }
        if (!S_ISREG(filesize1.st_mode)) {
            /* not a regular file */
            continue;
        }
        rewinddir(dir2);
        while ((dp2 = readdir(dir2)) != NULL) {
            /* ignore . and .. entries */
            if (!strcmp(dp2->d_name, ".")
            ||  !strcmp(dp2->d_name, ".."))
                continue;
            if (!buildpath(path2, sizeof path2, argv[2], dp2->d_name)) {
                /* path too long */
                continue;
            }
            if (stat(path2, &filesize2)) {
                /* cannot stat entry */
                continue;
            }
            if (!S_ISREG(filesize2.st_mode)) {
                /* not a regular file */
                continue;
            }
            if (filesize1.st_size == filesize2.st_size) {
                printf("%s and %s have the same size %llu\n",
                       path1, path2, (unsigned long long)filesize1.st_size);
                /* perform actual comparison... */
            }
        }
    }
    closedir(dir1);
    closedir(dir2);
    return 0;
}

您没有将来自dir1的所有文件与来自dir2的所有文件进行比较,您需要使用2个循环来完成此操作。您现在从每个目录中读取第一个文件,比较它们,然后从每个目录中读取下一个文件,比较它们,等等。直到其中一个目录中的文件用完或出现错误。您需要比较第一个文件dir1中的ile与dir2中的所有文件相对应,然后是dir1中的第二个文件与dir2中的所有文件相对应,等等。这可能取决于您的任务,但如果您确实在寻找重复文件,则应该对文件内容进行散列并比较散列。显然,两个文件可以大小相同,名称和扩展名相同,但内容不同nt。如果这是一个练习,那么正如@yano所提到的,您需要循环浏览文件并比较它们。或者,您可以像answer建议的那样使用FDUPE。对于一个目录,构建一个列表..或者更确切地说是属性的哈希表,然后扫描另一个,看看条目是否在此列表中。我添加了必要的while循环。然而,如此me文件不是随机比较的,有些文件显示0字节大小,但显然不是0字节…不允许散列,因为我们的老师希望我们使用Directories。我不明白您的第四点:请提供一个代码片段好吗?我正在重新打开内部while循环中的第二个条目。@paulwolf:在if filesize1中有一个额外的;项.st_size==filesize2.st_size;{printf%s和%s sind gleich\n,d_verzeichnis1->d_name,d_verzeichnis2->d_name;}.This;是一个空语句,使得if无效。代码非常有用,谢谢!但是我不理解这些部分:char*buildpathchar*dest,size\t size,const char*dir,const char*name和!buildPath1,sizeof path1,argv[1],dp1->d_name和!buildPath2,sizeof path2,argv[2],dp2->d_name?