⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3.c

📁 本程序的功能是在遍历目录树的基础上实现文件类型的,文件的比较,文件名匹配文件的查找,速度较快,只需输入要比较文件的文件名就可以进行比较,并可以输出查找结果
💻 C
字号:
#include "sys/types.h"
#include "sys/stat.h"
#include "dirent.h"
#include "limits.h"
#include "ourhdr.h"
#include "unistd.h"
#include "fcntl.h"
#include "pathalloc.c"
#include "error.c"

/* function type that is called for each filename */
typedef int Myfunc(char *, const struct stat *, int);

static Myfunc     myfunc;
static Myfunc     myfunc1;
static Myfunc     myfunc2;
static int        myftw(char *, Myfunc *);
static int        dopath(Myfunc *);

static int intype;				//标记输入命令的类型
static char *buf,*buf1;
static struct stat stabuf;
static char **p;			
static char *pargv;				//指向要进行比较的文件路径
static char *abspath;			//存放当前工作目录的绝对路径	
int filesnum;

static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot,nf4k=0;//nf4k存放文件长度小于4096字节的文件个数

int
main(int argc, char *argv[])
{
    int     ret;
	int intype;

	if(argc==2)		//输入类型判断
		intype=0;
	else if(strcmp(argv[2],"-comp")==0){		//若为comp情况
        pargv=argv[3];							//指向要进行比较的文件路径
		if(lstat(argv[3],&stabuf)<0)			//取要进行比较的文件(argv[3])的信息
			err_ret("stat error for %s",argv[3]);

		buf=(char *)malloc(stabuf.st_size *sizeof(char));		//用于读入argv[3]文件
		buf1=(char *)malloc(stabuf.st_size *sizeof(char));		//用于存放与之进行比较的文件
		int fd;
		if((fd=open(argv[3],O_RDONLY))==-1)			//打开argv[3]文件
			err_ret("can not open file: %s",argv[3]);
		if(read(fd,buf,stabuf.st_size)<0)			//读入argv[3]文件
			err_ret("can not read file: %s",argv[3]);
		intype=1;		
	}
	else if(strcmp(argv[2],"-name")==0){		//若为name情况
		filesnum=argc-3;						//存要进行比较的文件名个数
		p=(char **)malloc(filesnum*sizeof(char));//保存文件名
		int i;
		for(i=3;i<argc;i++)
			p[i-3]=argv[i];
		intype=2;
	}
	else{
		printf("input fomat error!");		//输入格式错误
		return;
	}
	chdir(argv[1]);			//当前工作目录转向给定的目录
	int size;
	abspath=path_alloc(&size);	//存放当前工作目录的绝对路径
	if(getcwd(abspath,size)==NULL)//取当前工作目录
		err_sys("getcwd failed!");
	char *pp;
	pp=".";				//pathname为当前工作目录即.

	if(intype==0){		
		ret = myftw(pp, myfunc);   
		ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
		if (ntot == 0)
			ntot = 1;       /* avoid divide by 0; print 0 for all counts */
		//输出相关信息
		printf("regular files  = %7ld, %5.2f %% %5.2f %%\n", nreg,nreg*100.0/ntot,nf4k*100.0/nreg);//nf4k为文件大小小于4096字节的文件数
	    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);
	}
	else if(intype==1)
		ret=myftw(pp,myfunc1);
	else
		ret=myftw(pp,myfunc2);

	exit(ret);
}

/*
 * Descend through the hierarchy, starting at "pathname".
 * The caller's func() is called for every file.
 */
#define FTW_F   1       /* file other than directory */
#define FTW_D   2       /* directory */
#define FTW_DNR 3       /* directory that can't be read */
#define FTW_NS  4       /* file that we can't stat */

static char *fullpath;      /* contains full pathname for every file */

static int                  /* we return whatever func() returns */
myftw(char *pathname, Myfunc *func)
{

    int len;
    fullpath = path_alloc(&len);    /* malloc's for PATH_MAX+1 bytes */
                                        /* (Figure 2.15) */
    strncpy(fullpath, pathname, len);       /* protect against */
    fullpath[len-1] = 0;                    /* buffer overrun */

    return(dopath(func));
}
/*
 * Descend through the hierarchy, starting at "fullpath".
 * If "fullpath" is anything other than a directory, we lstat() it,
 * call func(), and return. For a directory, we call ourself
 * recursively for each name in the directory.
 */
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) /* stat error */
        return(func(fullpath, &statbuf, FTW_NS));
    if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */
        return(func(fullpath, &statbuf, FTW_F));

     /*
      * It's a directory. First call func() for the directory,
      * then process each filename in the directory.
      */
    if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
        return(ret);

    ptr = fullpath + strlen(fullpath);      /* point to end of fullpath */
    *ptr++ = '/';
    *ptr = 0;

     if ((dp = opendir(fullpath)) == NULL)     /* can't read directory */
         return(func(fullpath, &statbuf, FTW_DNR));

     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 */

         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);
}

static int 
myfunc (char *pathname, const struct stat *statptr, int type)
{
	switch (type) {
    case FTW_F:
        switch (statptr->st_mode & S_IFMT) {
        case S_IFREG:    nreg++;   
			 if(statptr->st_size<=4096)
				 nf4k++;
			 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);
			break;                    /* 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);
		break;
    }

    return(0);
}

static int
myfunc1(char *pathname, const struct stat *statptr, int type)		//若pathname为const则不能该
{
	char *t;
	switch (type) {
	case FTW_F:
		if(stabuf.st_size==statptr->st_size){	//若两文件的大小相同
			int fd;
			if((fd=open(pathname,O_RDONLY))==-1)		//打开文件
				err_ret("can not open file: %s",pargv);
			if(read(fd,buf1,stabuf.st_size)<0)			//读入内容	
				err_ret("can not read file: %s",pargv);	
				/*if内容相同输出路径,close文件*/
			if(strcmp(buf,buf1)==0){			//若两文件内容相同
				if(strcmp(abspath,"/")!=0)		//若当前工作目录为根目录
					printf("%s",abspath);		//不输出当前工作目录的绝对路径
				    printf("%s\n",pathname+1);	//输出符合条件的文件的绝对路径
			}
			close(fd);							//关闭打开的文件
		}
		break;
    case FTW_D:
        break;
    case FTW_DNR:
        break;
    case FTW_NS:
        break;
    default:
        break;
    }
    return(0);
}




static int 
myfunc2 (char *pathname, const struct stat *statptr, int type)
{
	char *t;
	switch (type) {
	case FTW_F:
		t=pathname + strlen(pathname);
		while(*t!='/')							
			t--;
		t++;									//t指向pathname指向的文件名
		int i;
		for(i=0;i<filesnum;i++){				//分别与给定的文件名比较
			if(strcmp(t,p[i])==0){				//若文件名相同
				if(strcmp(abspath,"/")!=0)		//若当前工作目录为根目录
				printf("%s",abspath);			//不输出当前工作目录的绝对路径
			    printf("%s\n",pathname+1);		//输出符合条件的文件的绝对路径
			}
		}
        break;

    case FTW_D:
        ndir++;
        break;

    case FTW_DNR:
        break;

    case FTW_NS:
        break;

    default:
		break;
    }

    return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -