linux 获取文件元数据、文件夹的操作、ls功能实现

来源:互联网 发布:论坛软件有哪些 编辑:程序博客网 时间:2024/06/10 03:37

今天介绍linux中如何获取文件的元数据以及对文件夹的操作

首先 什么是文件的元数据?    

tarena@ubuntu:~/LIANXI/10.15$ ls -l a.c-rw-rw-r-- 1 tarena tarena 616 10月 15 21:07 a.c
上面这个就是文件的元数据,可以理解为文件的描述信息,文件的属性。

文件拥有者是一个用户,每个用户都有自己的id 叫UID

linux是一个多用户的操作系统,操作系统需要对用户进行管理,需要记录用户的信息。这些信息记录在 /etc/passwd 文件中

查看文件  cat  /etc/passwd  选取相关结果如下:

root:x:0:0:root:/root:/bin/bash
tarena:x:1000:1000:tarena,,,:/home/tarena:/bin/bash
上述以:隔开的信息依次是 :

用户名字:是否需要输入密码:用户ID:组ID:备注信息:用户主要工作目录:登录成功后执行的第一个程序

每一个文件都有自己的 inode ,一个inode可以对应多个文件,如果两个文件的inode相同,就说这两个文件是硬链接关系。

如何建立硬链接呢?

采用  (ln 源文件  目的文件 )  命令

又硬链接就有软连接偷笑,那么如何建立软连接?什么是软连接呢?

软连接相当于Windows中的快捷方式。

使用    (ln -s  源文件  目的文件(快捷方式))来建立



那么如何获取文件的元数据呢?

#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>int stat(const char *path, struct stat *buf);

使用函数stat(2)

功能:打开一个文件,获取元数据

参数:

        path-文件的路径

        buf-存放文件元数据的地址

返回值:成功返回0   失败返回-1 

buf  参数是一个结构体 struct stst 类型,文件的元数据就存在其中。下面是该结构体:(可通过man 2 stat  查看帮助手册查到)

           struct stat {               dev_t     st_dev;     /* ID of device containing file */               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 */文件的UID               gid_t     st_gid;     /* group ID of owner */文件的GID(组ID)               dev_t     st_rdev;    /* device ID (if special file) */               off_t     st_size;    /* total size, in bytes */文件的大小               blksize_t st_blksize; /* blocksize for file system I/O */               blkcnt_t  st_blocks;  /* number of 512B 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 */文件的最后用户改变时间           };

每一个结构体的类型可以通过预编译然后查看预编译文件查找。


下面介绍文件夹的操作

opendir(3)  readdir(3)  closedir(3)
首先 opendir(3)

#include <sys/types.h>#include <dirent.h>DIR *opendir(const char *name);
功能:打开一个文件夹

参数:name-指定了要打开的文件夹的名字

返回值:成功返回一个地址访问方式是DIR型  

           返回NULL代表错误 errno被设置

closedir(3):

int closedir(DIR *dirp);
功能:关闭一个打开的文件夹

参数:dirp-要关闭的问价夹的访问地址   opendir的返回值

返回值:成功返回0,失败返回-1


readdir(3)

#include <dirent.h>struct dirent *readdir(DIR *dirp);
           struct dirent {               ino_t          d_ino;       /* inode number */               off_t          d_off;       /* offset to the next dirent */               unsigned short d_reclen;    /* length of this record */               unsigned char  d_type;      /* type of file; not supported                                              by all file system types */               char           d_name[256]; /* filename */           };
功能:读取文件夹的内容

参数:dirp-文件夹的访问地址

返回值:一个指针 struct dirent *类型

下面演示上面介绍的函数的用法,代码如下:

  1 #include<stdio.h>  2 #include <dirent.h>  3 #include <time.h>  4 #include <sys/types.h>  5 #include <sys/stat.h>  6 #include <unistd.h>  7 #include <sys/types.h>  8 #include <pwd.h>  9 #include <grp.h> 10 void mode(int mode_t){ 11     if(mode_t & S_IRWXU & S_IRUSR)printf("r"); 12     else{printf("-");} 13     if(mode_t & S_IRWXU & S_IWUSR)printf("w"); 14     else{printf("-");} 15     if(mode_t & S_IRWXU & S_IXUSR)printf("x"); 16     else{printf("-");} 17     if(mode_t & S_IRWXG & S_IRGRP)printf("r"); 18     else{printf("-");} 19     if(mode_t & S_IRWXG & S_IWUSR)printf("w"); 20     else{printf("-");} 21     if(mode_t & S_IRWXG & S_IXUSR)printf("x"); 22     else{printf("-");} 23     if(mode_t & S_IRWXO & S_IROTH)printf("r"); 24     else{printf("-");} 25     if(mode_t & S_IRWXO & S_IWOTH)printf("w"); 26     else{printf("-");} 27     if(mode_t & S_IRWXO & S_IXOTH)printf("x"); 28     else{printf("-");} 29     return; 30 } 31 int main(int argc,char *argv[]){ 32     struct stat buf; 33     int num=stat(argv[1],&buf); 34     if(num==-1){ 35         perror("stat"); 36         return -1; 37     } 38         if(S_ISDIR(buf.st_mode)){      //判断是否是文件夹文件 39         DIR *dir=opendir(argv[1]); 40         struct dirent *gg; 41         while(gg=readdir(dir)){ 42             struct stat buf2; 43             char arr[256]={0}; 44             sprintf(arr,"%s/%s",argv[1],gg->d_name);    /*这一步很重要,现在的工作路径在当前文件
                                                              夹,我们进入文件夹去显示文件夹内的文件的信息时,需要设置路径*/ 45             int num1=stat(arr,&buf2); 46     if(num1==-1){ 47         perror("stat2"); 48         return -1; 49     } 50             printf(" %s",arr); 51             mode(buf2.st_mode); 52     printf(" %ld",buf2.st_nlink);//硬链接个数 53     printf(" %s",(getpwuid(buf2.st_uid))->pw_name);//用户ID 54     printf(" %s",(getgrgid(buf2.st_gid))->gr_name);//组ID 55     printf(" %ld",buf2.st_size);//文件大小 56     printf(" %s",ctime(&(buf2.st_mtime)));//修改时间 57         } 58         return 0; 59     } 60     if(S_ISREG(buf.st_mode)){ 61         printf("-"); 62     } 63     mode(buf.st_mode);//文件权限 64     printf(" %ld",buf.st_nlink);//硬链接个数 65     printf(" %s",(getpwuid(buf.st_uid))->pw_name);//用户ID 66     printf(" %s",(getgrgid(buf.st_gid))->gr_name);//组ID 67     printf(" %ld",buf.st_size);//文件大小 68     printf(" %s",ctime(&(buf.st_mtime)));//修改时间 69     return 0; 70 }
以上代码中的

ctime(&(buf.st_mtime)
getpwuid(buf.st_uid)
等函数可以通过手册查找到。

运行结果如下:

tarena@ubuntu:~/LIANXI/10.17$ ./a.out file file/test.crw-r--r-- 1 tarena tarena 4 Tue Oct 17 22:11:17 2017 file/.rwxr--r-x 2 tarena tarena 4096 Tue Oct 17 22:11:17 2017 file/..rwxr--r-x 3 tarena tarena 4096 Wed Oct 18 21:21:52 2017


该代码实际上实现了一个ls功能。大笑






原创粉丝点击