本文共 1615 字,大约阅读时间需要 5 分钟。
在计算机系统中,输入/输出(I/O)操作是主存与外部设备之间数据传输的关键环节。本文将深入探讨Unix系统下的文件操作机制,包括文件的打开、读写、关闭等方面的细节。
Unix系统将所有的I/O设备抽象为文件,这使得文件操作与设备操作具有一致性。程序通过读写文件进行I/O操作,而内核负责将操作转化为实际的设备访问。
打开文件
应用程序通过调用open()
函数,通知内核希望访问哪个文件。内核返回文件描述符(file descriptor),并记录文件的相关信息。每个进程开始时,通常会打开三个文件: 定位文件
文件的当前位置由lseek()
函数控制。内核维护一个偏移量k
,表示从文件开头开始的字节偏移。通过seek()
操作,可以将k
设定为任意值。读写文件
read()
函数返回实际读取的字节数,可能小于请求的n
,如文件末尾或网络缓存等原因。write()
函数返回实际写入的字节数,可能因存储空间不足或文件权限原因而受限。关闭文件
在文件操作完成后,必须通过close()
函数释放文件资源。内核会回收描述符表和文件表,并释放与文件相关的内存。open()
函数open()
函数的调用格式为:
int open(const char *filename, int flags, mode_t mode);
参数说明:
filename
:文件路径字符串。flags
:操作模式旗标,支持多种组合: O_RDONLY
:只读模式。O_WRONLY
:只写模式。O_RDWR
:读写模式。O_CREAT
:创建新文件。O_TRUNC
:截断现有文件。O_APPEND
:追加模式。mode_t mode
:文件权限标志,支持9种掩码位组合。可以用umask
函数设置默认权限。返回值:成功返回文件描述符,失败返回-1。
close()
函数close()
函数用于关闭文件描述符:
int close(int fd);
参数说明:fd
是要关闭的文件描述符。
返回值:成功返回0,失败返回-1。
read()
和write()
函数read()
函数:ssize_t read(int fd, void *buf, size_t n);
从文件中读取n
字节到buf
缓冲区。返回实际读取的字节数,或-1表示失败。
write()
函数:ssize_t write(int fd, const void *buf, size_t n);
将n
字节从buf
缓冲区写入文件。返回实际写入的字节数,或-1表示失败。
为了提升文件操作性能,可以使用rio
(Robust I/O)库。rio
提供两种无缓冲函数和带缓冲函数,适用于不同场景:
rio_readn()
和rio_writen()
函数无缓冲函数适用于网络传输或高效读写,直接传输数据。
rio_readlineb()
和rio_readnb()
函数带缓冲函数用于处理文本和二进制数据,支持行读写和大块读写。
通过stat()
和fstat()
函数,可以检索文件的元数据,如文件大小、权限、所有者、修改时间等。这些信息存储在struct stat
结构体中。
在Unix系统中,文件共享通过文件表实现。内核用描述符表和v-node表管理文件资源。dup2()
函数用于将描述符重定向到另一个描述符。
本文从基础的文件操作到高级的I/O优化,全面探讨了Unix系统下的文件操作机制。理解这些机制是掌握Linux系统编程的关键。
转载地址:http://xtkfk.baihongyu.com/