文件和目录
上一节主要讲述文件IO,这一节内容是文件系统的其他特征和文件的性质。
1.函数stat、fstat、fstatat和lstat
本节主要讨论四个函数:
#include
int stat(const char *restrict pathname, struct stat *restrict buf );
int fstat(int fd, struct stat *buf);
int lstat(const char *restrict pathname, struct stat *restrict buf );
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);
/* 返回值:成功返回0,失败返回-1 */
stat返回命名文件有关的信息结构;fstat获得描述符fd
上打开文件的有关信息;lstat类似stat,但是当命名文件是一个符号链接时返回该符号链接的有关信息而不是符号链接引用的文件,用于降序遍历目录层次结构;fstatat为一个相对于当前打开目录(fd
指向)的路径名返回文件统计信息,第二个参数buf是一个指针,指向我们必须提供的结构。
2.文件类型
Unix文件类型包括下面几种:
- 普通文件,包含某种形式的数据
- 目录文件,包含其他文件的名字以及指向与这些文件有关信息的指针,对一个目录文件具有读权限的任意进程都可以读该目录内容,但是只有内核可以直接写目录文件
- 块特殊文件,这种类型的文件提供对设备带缓冲的访问,每次访问以固定长度为单位进行
- 字符特殊文件,提供对设备不带缓冲的访问,每次访问长度可变
- FIFO,用于进程间通信,有时也称为命名管道
- 套接字,用于进程间网络通信
- 符号链接,用于指向另一个文件
3.设置用户ID和组ID
与一个进程关联的ID:
ID | 含义 |
---|---|
1.实际用户ID和实际组ID | 标志用户实际是谁 |
2.有效用户ID、有效组ID和附属组ID | 用于文件访问权限检查 |
3.保存的设置用户ID和设置组ID | 由exec函数保存 |
4.access和faccessat
这两个函数是按实际用户ID和实际组ID进行访问权限测试:
#include
int access(const char *pathname, int mode);
int faccessat(int fd, const char *pathname, int mode, int flag);
/* 返回值:成功0,失败-1*/
如果测试文件存在,mode
就为F_OK,否则mode
按下表位或:
mode | 说明 |
---|---|
R_OK | 测试读权限 |
W_OK | 测试写权限 |
X_OK | 测试执行权限 |
5.umask
umask为进程设置文件模式创建屏蔽字,并返回之前的值:
#include
mode_t umask(mode_t cmask);
/* 返回值:之前文件模式创建的屏蔽字*/
6.chmod、fchmod和fchmodat
这三个函数用于改变现有文件的访问权限:
#include
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int fd, const char *pathname, mode_t mode, int flag);
/* 返回值:成功返回0,失败返回-1 */
chmod函数在指定文件上进操作,而fchmod函数则在已打开文件进行操作,fchmodat中,flag
可以改变fchmodat的行为。
7.文件截断
调用函数truncate和ftruncate可以截断文件:
#include
int truncate(const char *pathname, off_t length); int ftruncate(int fd, off_t length);
/* 返回值:成功0,失败-1*/
将现有文件长度截断为length
,如果文件以前长于length
则超过length
部分不能访问,若以前文件小于length
则文件长度增加,以前文件尾部和新的文件尾部直接产生空洞。
8.文件系统
首先介绍Unix文件系统的基本结构,我们可以把一个磁盘分为一个或多个分区,每个分区可以包含一个文件系统。i节点是固定长度的记录项,包含有关文件的大部分信息:
进一步i节点(索引节点)的结构:
- 在图中有两个目录项指向同一个i节点,每个i节点有一个链接计数,其值表示指向该i节点的目录项数,在stat结构中,链接计数包含在
st_nlink
成员中,这种链接称为硬链接 - 对应硬链接存在一种符号链接,符号链接的实际内容包含了该符号链接所指向的文件的名字。
- i节点包含了文件有关的所有信息:文件类型、文件访问权限位、文件长度和指向文件数据块的指针等。
9.符号链接
符号链接是对一个文件的间接指针,与硬链接不同,硬链接直接指向文件的i节点。引入符号链接的原因是避开硬链接的一些限制:
- 硬链接通常要求链接和文件位于同一文件系统
- 只有超级用户才能创建指向目录的硬链接
对于符号链接以及它指向何种对象并无任何文件系统限制,任何用户都可以创建指向目录的符号链接。符号链接一般用于将一个文件或整个目录结构移到系统中另一个位置。
当使用以名字引用文件的函数时,应当了解该函数是否处理符号链接。也就是该函数是否跟随符号链接到达它所链接的文件。如果该函数具有处理符号链接的功能,则其路径名参数引用由符号链接指向文件。否则,一个路径名参数引用链接本身,而不是由该链接指向的文件。
函数 | 是否跟随符号链接 |
---|---|
access | y |
chdir | y |
chmod | y |
chown | y |
creat | y |
exec | y |
lchown | n |
link | y |
lstat | n |
open | y |
opendir | y |
pathconf | y |
readlink | n |
remove | n |
rename | n |
stat | y |
truncate | y |
unlink | n |
小结
这节内容真的很多,涉及到很多用户权限问题,比较难消化。