码迷,mamicode.com
                                                                              首页 > 其他好文 > 详细

                                                                              第四章:文件和目录

                                                                              时间:2019-05-09 13:49:03      阅读:24      评论:0      收藏:0      [点我收藏+]

                                                                              标签:节点   sock   back   开头   修改   限时   ati   介绍   flag   

                                                                               


                                                                              本章在第三章的基础上描述文件的属性,如大小、创建时间等。

                                                                              本章最后介绍对目录进行操作的各个函数。


                                                                               

                                                                               

                                                                              一、stat()、fstat()、fstatat()和lstat()

                                                                              stat系列函数用于返回文件的属性信息,如文件类型、大小、所有者、访问修改时间等。函数声明如下:

                                                                               1 /* 文件属性查看函数 */
                                                                               2 #include <sys/stat.h>
                                                                               3 
                                                                               4 int stat(const char *pathname, struct stat *buf);
                                                                               5 int fstat(int fd, struct stat *buf);
                                                                               6 int lstat(const char *pathname, struct stat *buf);
                                                                               7 int fstatat(int fd, const char *pathname, struct stat *buf, int flags);
                                                                               8 
                                                                               9 /* 例子 */
                                                                              10 struct stat st;
                                                                              11 fstat(fd, &st);
                                                                              12 char *buf;
                                                                              13 
                                                                              14 if (S_ISREG(st.st_mode))
                                                                              15     buf = "regular";             /* 普通文件 */
                                                                              16 else if (S_ISDIR(st.st_mode))
                                                                              17     buf = "directory";            /* 目录 */
                                                                              18 else if (S_ISCHR(st.st_mode))
                                                                              19     buf = "character special";    /* 字符文件 */
                                                                              20 else if (S_ISBLK(st.st_mode))
                                                                              21     buf = "block special";        /* 块文件 */
                                                                              22 else if (S_ISFIFO(st.st_mode))
                                                                              23     buf = "fifo";                 /* 管道文件 */
                                                                              24 /*
                                                                              25 else if (S_ISLINK(st.st_mode))
                                                                              26     buf = "link";                 /* 链接文件,使用fstat()无法识别 */
                                                                              27 */
                                                                              28 else if (S_ISSOCK(st.st_mode))
                                                                              29     buf = "socket";               /* 网络套接字 */
                                                                              30 else
                                                                              31     buf = "unknow mode";
                                                                              32     
                                                                              33 printf("%s\n", buf);

                                                                               


                                                                              函数参数以及返回值:

                                                                              pathname:文件路径名

                                                                              buf:返回的stat结构体

                                                                              fd:文件打开函数返回的文件描述符

                                                                              flags:标识符

                                                                              返回值:成功返回0;出错返回-1。


                                                                               

                                                                              上面函数返回的stat结构体各个实现可能存在差异,但它们都至少具备下列的信息:

                                                                               1 struct stat {
                                                                               2     mode_t                st_mode;    // 文件类型和访问权限
                                                                               3     ino_t                st_ino;        // 指向数据块的节点的编号
                                                                               4     dev_t                st_dev;        // 设备号
                                                                               5     dev_t                st_rdev;                
                                                                               6     nlink_t                st_nlink;    // 硬链接数
                                                                               7     uid_t                st_uid;        // 用户ID
                                                                               8     gid_t                st_gid;        // 用户组ID
                                                                               9     off_t                st_size;
                                                                              10     struct timespec        st_atim;    // 数据访问时间
                                                                              11     struct timespec        st_mtim;    // 数据修改时间
                                                                              12     struct timespec        st_ctim;    // 属性修改时间
                                                                              13     blksize_t            st_blksize;    // 最好的IO块大小
                                                                              14     blkcnt_t            st_blocks;
                                                                              15 };

                                                                               

                                                                               

                                                                              二、文件类型

                                                                              UNIX系统中的文件大多数是普通文件和目录,但也存在其他类型的文件,其分类如下:

                                                                              普通文件(regular file):包含数据的常规文件,数据可以是文本类型的,也可以是二进制的。

                                                                              目录文件(directory file):它是一个目录,保存目录相关的信息。

                                                                              块设备文件(block special file):这种文件提供对硬件(如磁盘)带缓冲的访问

                                                                              字符设备文件(regular file):这种文件提供对硬件(如磁盘)不带缓冲的访问

                                                                              FIFO:这种文件用于进程间通信。

                                                                              套接字文件(regular file):这种文件用于网络间通信。

                                                                              符号连接(regular file):类似Windows系统的快捷方式,指向另外一个文件。

                                                                               

                                                                              以上文件类型的信息存储在前面说明的stat结构体中st_mode成员中的。正如我所给出的上面的例子,st_mode成员的读取是利用系?#31243;?#20379;的宏函数进行的。在此我总结以下上文例子中的宏函数:

                                                                              S_ISREG()        /* 普通文件 */
                                                                              S_ISDIR()        /* 目录 */
                                                                              S_ISCHR()        /* 字符文件 */
                                                                              S_ISBLK()        /* 块文件 */
                                                                              S_ISFIFO()        /* 管道文件 */
                                                                              S_ISLINK()        /* 链接文件 */
                                                                              S_ISSOCK()        /* 网络套接字 */

                                                                               

                                                                               

                                                                              三、文件访问权限

                                                                              stat结构体中st_mode成员还包含有文件的访问权限,访问权限曾在第三章第二节有简单的演示。

                                                                              为了打开?#25105;?#31867;型的一个文件,则需要对该文件所在的父级以及父级的父级等目录具有执行权限。删除一个文件不需要对该文件有任何权限,只需要对被删除文件的父级目录具?#34892;?#21644;执行权限即可。

                                                                               

                                                                              进程?#30475;?#25171;开、创建或删除一个文件时,内核就对该文件进行访问权限测试,通常的步骤是:

                                                                              1. 先判断进程是否是超级用户,即ID是否为0,是则允许访问,否则执行第二步;

                                                                              2. 再判断进程的?#34892;?#29992;户ID是否等于文件的所有者ID,如果是并且被访问文件设定了?#23454;?#30340;?#21015;?#26435;限,则允许访问;否则执行第三步;

                                                                              3. 然后判断进程?#34892;?#32452;ID或者附加组ID是否等于文件的组ID,如果是并且被访问文件设定了?#23454;?#30340;?#21015;?#26435;限,则允许访问;否则执行第四步;

                                                                              4. 最后查看文件的其他用户是否有?#23454;?#26435;限访问文件,?#24615;?#20801;许,否则判断结束、访问失败。

                                                                               

                                                                               

                                                                              四、access()和faccessat()

                                                                              access()和faccessat()函数可用于判?#31995;?#21069;用户是否具有访问某个文件的权限。函数声明如下:

                                                                               1 /* 权限检测函数 */
                                                                               2 #include <unistd.h>
                                                                               3 
                                                                               4 int access(const char *pathname, int mode);
                                                                               5 int faccessat(int fd, const char *pathname, int mode, int flags);
                                                                               6 
                                                                               7 /* 例子 */
                                                                               8 if (access("a.txt", R_OK) == 0)        /* 是否有读权限 */
                                                                               9     printf("a.txt read ok\n");
                                                                              10 if (access("a.txt", W_OK) == 0)        /* 是否?#34892;?#26435;限 */
                                                                              11     printf("a.txt write ok\n");
                                                                              12 if (access("a.txt", X_OK) == 0)        /* 是否有执行权限 */
                                                                              13     printf("a.txt execute ok\n");

                                                                               


                                                                              函数参数以及返回值:

                                                                              pathname:文件路径名

                                                                              mode:模式,包含有R_OK、W_OK、X_OK和F_OK

                                                                              flags:标识符

                                                                              返回值:有权限返回0


                                                                               

                                                                               

                                                                              五、文件操作其他函数

                                                                              权限屏蔽函数umask(),用于设置创建新文件时的权限屏蔽字,对于修改文件权限时权限屏蔽字没?#34892;?#26524;,函数声明如下:

                                                                               

                                                                              #include <sys/stat.h>
                                                                              
                                                                              mode_t umask(mode_t mask);
                                                                              
                                                                              /* 例子 */
                                                                              mode_t old = umask(0222);    /* 如果原来的权限是0777,那么最终的结果是077 - 0222 = 0555,old返回原来的权限 */
                                                                              umask(old);    /* ?#25351;?#26435;限 */

                                                                               

                                                                              chmod()、fchmod()和fchmodat()这三个函数用于更改文件的访问权限。函数声明如下:

                                                                               

                                                                              1 #include <sys/stat.h>
                                                                              2 
                                                                              3 int chmod(const char *file, mode_t mode);
                                                                              4 int fchmod(int fd, mode_t mode);
                                                                              5 int fchmodat(int fd, const char *file, mode_t mode, int flag);
                                                                              6 
                                                                              7 /* 例子 */
                                                                              8 fchmod(fd, 0666);    /* 更改权限为0666 */

                                                                               

                                                                              权限改变成功则返回0,失败返回-1。

                                                                               

                                                                               

                                                                              六、目录相关函数

                                                                               

                                                                               1 #include <dirent.h>
                                                                               2 
                                                                               3 /* 打开一个目录 */
                                                                               4 DIR *opendir(const char *name);    // 成功返回指针,失败返回NULL
                                                                               5 DIR *fdopendir(int fd);                     // 成功返回指针,失败返回NULL
                                                                               6 
                                                                               7 /* 读取目录中的内容,如文件、子目录 */
                                                                               8 struct dirent *readdir(DIR *dirp);     // 成功返回指针,失败返回NULL
                                                                               9 
                                                                              10 /* 让目前的读取位置还原到开头的读取位置 */
                                                                              11 void rewinddir(DIR *dirp);
                                                                              12 
                                                                              13 /* 设置相对于开头偏移值为pos的读取位置 */
                                                                              14 void seekdir(DIR *dirp, long int pos);
                                                                              15 
                                                                              16 /* 关闭目录 */
                                                                              17 int closedir(DIR *dirp);                // 成功时返回0,失败返回-1
                                                                              18 
                                                                              19 /* 例子 */
                                                                              20 DIR* dir = opendir("../");
                                                                              21 struct dirent* ent;
                                                                              22 while(ent=readdir(dir)) // 1 读, 2 =,3 判断ent是否为0
                                                                              23 {
                                                                              24     printf("%d, %s\n", ent->d_type, ent->d_name);
                                                                              25 }    // d_tpye == 4 的是目录
                                                                              26 closedir(dir);

                                                                              读某个目录内容(子项)的步骤:
                                                                              1. opendir()返回目录指针
                                                                              2. 循?#36820;?#29992;readdir(),逐一读取每个子项
                                                                              3. closedir()关闭目录,这步也可以省略

                                                                               

                                                                              第四章:文件和目录

                                                                              标签:节点   sock   back   开头   修改   限时   ati   介绍   flag   

                                                                              原文地址:https://www.cnblogs.com/Lioker/p/10682870.html

                                                                              (0)
                                                                              (0)
                                                                                 
                                                                              举报
                                                                              评论 一句话评论(0
                                                                              0条  
                                                                              登录后才能评论!
                                                                              ? 2014 mamicode.com 版权所有 京ICP备13008772号-2
                                                                              迷上了代码!
                                                                              宁夏11选5开奖查询