目录
符号链接文件
符号链接(symbolic link,简称symlink)是一种特殊的文件类型,每个符号链接都有自己独立的i节点和包含目标文件完整路径名的数据块。与硬链接相比,符号链接解析时需要更大的系统开销,因为它需要解析两次文件:首先是符号链接文件本身,然后是链接的目标文件。文件系统为硬链接维护链接计数,但不对符号链接维护任何链接计数信息。
文件类型及其权限
在Unix-like系统中,文件类型主要包括:
- 普通文件(regular file)
- 目录(directory),用'd'表示
- 本地套接字(socket),用's'表示
- 字符设备(character device),用'c'表示
- 块设备(block device),用'b'表示
- 符号链接(symbolic link),用'l'表示
- 有名管道(named pipe),用'p'表示
文件权限使用'rwx'三位一组表示读、写、执行权限,每种权限的权重分别为'r'(4)、'w'(2)和'x'(1)。例如,权限777表示用户、用户组成员和其他人都具有读、写、执行权限,而771则表示除去其他用户的写权限。
权限掩码(umask)决定了新建文件的默认权限。例如,如果umask为0002,那么赋予0777权限的文件最终权限会变成0775,即取消了除文件所有者之外的其他用户对该文件的写权限。
文件的内核结构
当一个文件被打开时,操作系统会在内核中为该文件维护一套专用的数据结构,即文件表项,直至文件被关闭。文件表项包括了文件的状态、读写位置以及指向v节点(或称为inode)的指针。v节点包含了文件的元数据信息以及i节点信息,将i节点数据从磁盘加载到内存中,以便快速访问。
文件描述符表
操作系统维护了一个文件描述符表,键为文件描述符,从0开始编号,0、1、2分别预留给标准输入、标准输出和标准错误。值为文件表项的指针,通过文件描述符,操作系统可以找到对应的文件表项,进而通过v节点指针定位到v节点,然后通过v节点中的i节点找到数据块编号,从而访问到文件的实际内容。
文件的读写位置随着读写操作的执行而动态更新。lseek
系统调用可以人工调整文件的读写位置,接受三个参数:文件描述符、偏移量和基准位置(如SEEK_SET、SEEK_CUR或SEEK_END),并返回调整后的文件读写位置。
系统I/O与标准I/O
在进行大量重复写入操作时,使用fwrite
(属于标准I/O库函数)相比直接调用write
(系统调用)通常更快,因为标准I/O库会在内部实现缓冲机制。当数据积累到一定程度时,才一次性调用write
将缓冲区内容写入磁盘。
文件描述符复制
dup
和dup2
系统调用用于复制文件描述符。dup
会返回一个新的文件描述符,与原有描述符指向同一个文件表项。而dup2
则更具针对性,它可以将一个已存在的文件描述符复制到另一个文件描述符上,如果目标描述符已打开,则可能被关闭。
文件控制:fcntl函数
fcntl
函数提供了对已打开文件的多种控制操作。其中一个常用的选项是F_DUPFD
,它会返回一个新的文件描述符,新描述符与原来的描述符指向同一个文件表项,但其值为newfd
(或大于newfd
的最小可用文件描述符)。fcntl
通过不同的宏定义提供了丰富的文件控制功能,例如改变文件状态标志、设置文件锁定等。
总结起来,理解文件系统中符号链接、权限管理、内核结构以及系统I/O和文件控制机制,是深入学习操作系统和文件系统的基础。这些知识对于编写高效、稳定的程序至关重要