当先锋百科网

首页 1 2 3 4 5 6 7
第三章


3.1 引言
UNIX系统中的大多数文件I/O只需用到5个函数:open、read、write、lseek以及close。
本章所说明的函数经常被称为不带缓冲的I/O。术语不带缓冲指每个read和write都调用内核中的一个系统调用。


3.2 文件描述符
所有打开的文件都通过文件描述符引用,它是一个非负整数。
按照惯例,文件描述符0表示进程的标准输入,1表示标准输出,2表示标准出错。
POSIX中将0、1、2用符合常量替换:STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。定义在<unistd.h>中。


3.3 open函数
#include<fcntl.h>
int open(const char *pathname,int oflag,...);//成功返回文件描述符,失败返回-1.
pathname是要打开或创建的文件名.
oflag参数为一些常量进行或的结果,如O_RDONLY、O_WRONLY、O_RDWR(以上三选一)和O_APPEND、O_CREAT等。
由open函数返回的文件描述符一定是最小的未用描述符数值。


3.5 close函数
#include<unistd.h>
int close(int filedes);//成功返回0,出错返回-1.
当一个进程终止时,内核自动关闭它所有打开的文件,很多程序利用这一功能而不显示用close关闭打开文件。


3.6 lseek函数
每个打开的文件都有一个“当前文件偏移量”,度量从文件开始出计算的字节数,当打开一个文件时,除非指定O_APPEND,否则偏移量设
为0。
可以调用lseek显示地为一个打开的文件设置其偏移量。
#include<unistd.h>
off_t lseek(int filedes,off_t offset,int whence);//成功返回新的文件偏移量,出错返回-1.off_t相当于长整型
对参数offset的解释和参数whence的值有关。
1.若whence是SEEK_SET,则偏移量设置为文件开始处offset个字节。
2.若whence是SEEK_CUR,则偏移量设置为其当前值加offset,offset可正可负。
3.若whence是SEEK_END,则偏移量设置为文件长度加offset,offset可正可负。
lseek仅将当前的文件偏移量记录在内核中,它并不引起任何I/O操作。文件中的空洞并不要求在磁盘上占用存储区。


3.7 read函数
#include<unistd.h>
ssize_t read(int filedes,void *buf,size_t nbytes);//成功返回读到的字节数,若已到文件结尾返回0,出错返回-1.ssize_t有符号整
数,size_t无符号.
有多种情况可使实际读到的字节数少于要求读的字节数。如到达文件尾端。
读操作从文件的当前偏移量处开始,在成功返回之前,该偏移量将增加实际读到的字节数。


3.8 write函数
#include<unistd.h>
ssize_t write(int filedes,const void *buf,size_t nbytes);//成功返回已写的字节数,出错返回-1
返回值通常与参数nbytes的值相同,否则表示出错。


3.10 文件共享
内核使用三种数据结构表示打开的文件。
(1)每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表。
(2)内核为所有打开文件维持一张文件表。
(3)每个打开文件都有一个v节点(v-node)结构。


3.11 原子操作
把定位和读写作为一个原子操作.
#include<unistd.h>
ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);//返回读到的字节数,若到文件尾返回0,出错返回-1.
ssize_t pwrite(int filedes, const void *buf, size)t nbytes, off_t offset);//成功返回已写字节数,出错返回-1.
调用pread相当于顺序调用lseek和read但是无法中断其定位和读操作。pwrite类似。


3.12 dup和dup2函数
dup和dup2函数可用来复制一个现存的文件描述符。
int dup(int filedes);
int dup2(int filedes1, int filedes2);//成功返回新的文件描述符,出错返回-1.
dup返回的新描述符一定是当前可用文件描述符的最小数值,dup2可用filedes2参数指定新描述符的数值。
fcntl函数也可复制一个文件描述符。


3.13 文件同步
sync:将修改过的块排入写队列,然后返回,并不等待实际的写磁盘操作结束。
fsync:等待写入磁盘完成,并改变属性。
fdatesync:同上,只影响文件的数据部分,而不改变属性。


3.14 fcntl函数
fcntl函数有5种功能:
(1)复制一个现有的描述符
(2)获得/设置文件描述符标记
(3)获得/设置文件状态标志
(4)获得/设置异步I/O所有权
(5)获得/设置记录锁


3.16 /dev/fd
打开文件/dev/fd/n等效于复制文件描述符n(假定描述符n是打开的)。
/dev/fd文件主要由shell使用,允许使用路径名作为调用参数的程序,能用处理其他路径名的相同方式处理标准输入和输出。