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?