📄 3.c
字号:
//main函数:
int main(int argc, char *argv[])
{
int tag = 0;
int ret,i;
if (argc == 4 && !strcmp(argv[2],"-comp"))
{
tag = 1;
if((fp = open(argv[3],O_RDONLY))<0) //打开要进行比较的文件
err_sys("open file error");
filelength=lseek(fp,0,SEEK_END);
buf=(char *)malloc((filelength)*sizeof(char));
lseek(fp,0,SEEK_SET);
if(read(fp,buf,filelength)<0) //将该文件的内容读入到一个数组中保存
err_sys("file read error");
ret = myftw(argv[1],myfunc2);
free(buf);
}
if (argc >= 4 && !strcmp(argv[2],"-name") )
{
tag = 1;
filenum=argc-3; //统计要进行查找的文件的数量
for(i=0;i<filenum;++i)
dirfile[i] = path_alloc(NULL);
for(i=0;i<filenum;++i) //将要进行比较的文件的名字保存到一个数组中
strcpy(dirfile[i],argv[3+i]);
ret = myftw(argv[1],myfunc3);
}
if (argc == 2)
{
tag = 1;
ret = myftw(argv[1],myfunc);
if((ntot=nreg+ndir+nblk+nchr+nfifo+nslink+nsock) ==0 )
ntot = 1; /* avoid divide by 0; print 0 for all counts */
printf("\nregular files = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
printf("directories = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);
printf("block special = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);
printf("char special = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
printf("symbolic links = %7ld, %5.2f %%\n", nslink,nslink*100.0/ntot);
printf("sockets = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);
printf("f_size<=4096B = %7ld, %5.2f %%\n", nb4096,nb4096*100.0/nreg); //输出文件大小小于4096的文件的//数量和所占百分比
}
if( !tag )
err_quit("usage: myfind <pathname> [-comp<filename>|-name<str>...]");
printf("\n");
exit(0);
}
//dopath函数
static int /* we return whatever func() returns */
dopath(Myfunc* func)
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int ret;
char *ptr;
if (lstat(fullpath, &statbuf) < 0)
return(func(fullpath, &statbuf, FTW_NS)); /* stat error */
if (S_ISDIR(statbuf.st_mode) == 0)
return(func(fullpath, &statbuf, FTW_F)); /* not a directory */
if ( (ret = func(fullpath, &statbuf, FTW_D)) != 0)
return(ret);
ptr = fullpath + strlen(fullpath); /* point to end of fullpath */
if(*(ptr-1)!='/') //判断路径中是否已经含有‘/’,若有则不加‘/’
*ptr++ = '/';
*ptr = 0;
if ( (dp = opendir(fullpath)) == NULL)
return(func(fullpath, &statbuf, FTW_DNR));
/* can't read directory */
while ( (dirp = readdir(dp)) != NULL) {
if (strcmp(dirp->d_name, ".") == 0 ||
strcmp(dirp->d_name, "..") == 0)
continue; /* ignore dot and dot-dot */
strcpy(ptr, dirp->d_name); /* append name after slash */
strcpy(filename,dirp->d_name);
if ( (ret = dopath(func)) != 0) /* recursive */
break; /* time to leave */
}
ptr[-1] = 0; /* erase everything from slash onwards */
if (closedir(dp) < 0)
err_ret("can't close directory %s", fullpath);
return(ret);
}
//3个操作函数:
static int myfunc(const char *pathname, const struct stat *statptr, int type)
{
struct stat statfile;
switch (type) {
case FTW_F:
switch (statptr->st_mode & S_IFMT) {
case S_IFREG: nreg++;
stat(pathname,&statfile);
if(statfile.st_size <= 4096) //判断文件大小是否小于4096B,若小于则进行记数加1
nb4096++;
break;
case S_IFBLK: nblk++; break;
case S_IFCHR: nchr++; break;
case S_IFIFO: nfifo++; break;
case S_IFLNK: nslink++; break;
case S_IFSOCK: nsock++; break;
case S_IFDIR:
err_dump("for S_IFDIR for %s", pathname);
/* directories should have type = FTW_D */
}
break;
case FTW_D:
ndir++;
break;
case FTW_DNR:
err_ret("can't read directory %s", pathname);
break;
case FTW_NS:
err_ret("stat error for %s", pathname);
break;
default:
err_dump("unknown type %d for pathname %s", type, pathname);
}
return(0);
}
static int myfunc2(const char *pathname,const struct stat *statptr, int type)
{
char *readfile,*path;
int f;
const size_t size=200;
char T_path[size];
if(type == FTW_F)
{
if(statptr->st_size != filelength) //先判断文件大小是否相同
return(0);
if((f=open(pathname,O_RDONLY))<0) //打开要读取的文件
err_sys("open file error");
readfile=(char *)malloc(filelength*sizeof(char));
if(read(f,readfile,filelength)<0) //将该文件的内容写入到一个数组中去
err_sys("read file error");
readfile[filelength]='\0';
if(strcmp(buf,readfile) == 0) //比较文件内容是否相同
{
printf("\n");
path=getcwd(T_path,size); //获得当前工作程序的绝对路径
all_path(path,pathname); //输出该文件所在的绝对路径
}
free(readfile);
}
return(0);
}
static int myfunc3(const char *pathname,const struct stat *statptr,int type)
{
int i;
const size_t size=200;
char A_path[size];
if(type==FTW_F)
{
getcwd(A_path,size); //获得当前工作程序的绝对路径
for(i=0;i<filenum;++i) //遍历查找是否该文件与所给文件中的一个名字相同
if(!strcmp(dirfile[i],filename))
{
printf("\n");
all_path(A_path,pathname);
}
}
return(0);
}
//输出绝对路径的函数:
static int all_path(char *A_path,const char *pathname)
{
char *path;
path = path_alloc(NULL);
strcpy(path,pathname);
int i=0,j=strlen(A_path);
while(*path=='.')
{
i++;
if(path[i]=='/'&&i==2) //判断输入的路径中是否含有向上退一级的符号 ../ 若有则对两个路径进行相应的处理
{
path=path+i+1; //将指针指向 . . / 后面的第一个地址
do{
*(A_path+j-1)='\0'; //将当前工作路径退一个文件夹
--j;
} while(*(A_path+j-1)!='/');
if(i==1) //若路径中含有 . ,则表示为当前文件夹,将path指向下一个地址
path++;
i=0; //重新记数判断
}
}
printf("%s\n",strcat(A_path,path));
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -