linux中用c实现find命令

本文介绍了Linux系统中用于文件和目录操作的几个关键函数,包括stat用于获取文件状态信息,access用于检查文件访问权限,以及dirent用于遍历目录。stat结构体包含了文件的各种属性,如文件类型、大小、访问时间等,access函数通过F_OK等常量检查文件是否存在,而dirent结构体和opendir/readdir等函数则用于目录的遍历。通过对这些函数的理解和使用,可以实现对Linux文件系统的深入操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现find shell

struct stat

保存文件状态信息

//stat结构体的详细信息
struct stat  
{   
    dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/  
    ino_t       st_ino;     /* inode number -inode节点号*/    
    mode_t      st_mode;    /* protection -保护模式*/    
    nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/    
    uid_t       st_uid;     /* user ID of owner -user id*/    
    gid_t       st_gid;     /* group ID of owner - group id*/    
    dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/    
    off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/    
    blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/    
    blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/    
    time_t      st_atime;   /* time of last access -最近存取时间*/    
    time_t      st_mtime;   /* time of last modification -最近修改时间*/    
    time_t      st_ctime;   /* time of last status change - */    
};  

tips:这里需要注意的是 st_mode 这个域不像其他域那么容易使用,需要一些宏予以配合。实际上这些宏就是一些特定位置为1的二进制数的绰号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。

文件类型标志包括:
S_IFBLK:文件是一个特殊的块设备
S_IFDIR:文件是一个目录
S_IFCHR:文件是一个特殊的字符设备
S_IFIFO:文件是一个FIFO设备
S_IFREG:文件是一个普通文件
S_IFLNK:文件是一个符号链接

还有一些用于帮助确定文件类型的宏定义,这些和上面的宏不一样,这些是带有参数的宏,类似与函数的使用方法:

S_ISBLK:测试是否是特殊的块设备文件
S_ISCHR:测试是否是特殊的字符设备文件
S_ISDIR:测试是否是目录
S_ISFIFO:测试是否是FIFO设备
S_ISREG:测试是否是普通文件
S_ISLNK:测试是否是符号链接
S_ISSOCK:测试是否是socket

//使用详情
//需要包含头文件
#include <sys/stat.h>   //结构体stat
struct stat st_buf;
char *url = "/home/user/文档/test";	//文件路径
int res = stat(url, &st_buf);    //通过文件路径url获取文件信息,并保存在stat结构体st_buf中,
if (res != 0) {
        cout << "FAILD,the error is " << errno << endl;   //错误,输出错误代码
    } else {
        cout << "the file is exit" << endl;  	//res == 0表示该文件信息存在
        
//判断一个文件是否是目录
	//1、使用S_IFREG $st_buf.st_mode
     if(S_IFREG & st_buf.st_mode){}
     
   //2、使用S_ISREG(st_buf.st_mode)
     if(S_ISREG(st_buf.st_mode)){}
    }

判断目录/文件是否存在

方法一----access()函数

定义函数:int access(const char * pathname, int mode)
函数说明:确定文件或文件夹的访问权限。pathname是文件的路径名+文件名,mode取值如下:

F_OK 值为0,判断文件是否存在
X_OK 值为1,判断对文件是可执行权限
W_OK 值为2,判断对文件是否有写权限
R_OK 值为4,判断对文件是否有读权限
>注:后三种可以使用或“|”的方式,一起使用,如W_OK|R_OK

返回值:如果指定的存取方式有效,则函数返回0,否则函数返回-1。

//需要头文件
//linux下的
    #include <unistd.h>    
    char *url = "/home/user/文档/test";	//文件路径
    if(access(name,F_OK)==0){ 
            cout<<("文件存在");<<endl;
    }
    //或者
    if (access(url,0)){ //access()函数的第一个参数是char *    
        cout<<"the file is not exit"<<endl;		//access(url,0) = -1
    }else{
        cout<<"the file is exit"<<endl;	//access(url,0) = 0
    }

方法二----stat()函数

定义函数: int stat(const char *file_name, struct stat *buf); 函数说明:
获取文件状态。通过文件名filename获取文件信息,并保存在buf所指的结构体stat中 返回值:
执行成功则返回0,失败返回-1,错误代码存于errno

errno
错误代码 1:ENOENT 参数file_name 指定的文件不存在
错误代码 2:ENOTDIR 路径中的目录存在但却非真正的目录
错误代码 3:ELOOP 欲打开的文件有过多符号连接问题, 上限为16 符号连接
错误代码 4:EFAULT 参数buf 为无效指针, 指向无法存在的内存空间
错误代码 5:EACCESS 存取文件时被拒绝
错误代码 6:ENOMEM 核心内存不足 错误代码 7:ENAMETOOLONG 参数file_name 的路径名称太长

//需要头文件
    #include <sys/stat.h>   //结构体stat
    char *url = "/home/user/文档/test";	//文件路径
    struct stat st_buf;
    int res = stat(url, &st_buf);    //通过文件路径url获取文件信息,并保存在st_buf中
    if (res != 0) {
        cout << "FAILD,the error is " << errno << endl;   //错误,输出错误代码
    } else {
        cout << "the file is exit" << endl;

struct dirent

//stat结构体的详细信息
struct dirent
{
   long d_ino; /* inode number 索引节点号 */
   off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
   unsigned short d_reclen; /* length of this d_name 文件名长 */
   unsigned char d_type; /* the type of d_name 文件类型 */
   char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
//使用详情
//需要头文件
    #include <dirent.h> //结构体dirent
    
    struct dirent *pdirent;
    DIR *d_info = opendir(url);  
    //获取url子目录下的所有文件和目录的列表,如果path是个文件则返回值为NULL

opendir()

函数原型:DIR* opendir (const char * path );
(获取path子目录下的所由文件和目录的列表,如果path是个文件则返回值为NULL)
函数功能:打开一个目录,在失败的时候返回一个空的指针。
DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息。
函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp,long loc);

readdir()

map<string,int>mymap
mymap.count
DIR *d_info = opendir()
struct dirent pdirent = readdir()
DT_DIR
DT_REG
strcpy()
strcmp()
strrchr()
strcat()
char * 与 char[]
初始化char a[256] = “”

https://www.cnblogs.com/scut-linmaojiang/p/4742617.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值