每个打开文件都有一个与其相关联的“当前文件偏移量”。它是一个非负整数,用以度量从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。
可以调用l s e e k显式地定位一个打开文件。
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int filesdes, off_t offset, int whence) ;
返回:若成功为新的文件位移,若出错为- 1。
对参数offset 的解释与参数w h e n c e的值有关。 若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset 个字节。若whence是SEEK_CUR ,则将该文件的位移量设置为其当前值加offset,offset可为正或负。 若whence是SEEK_END ,则将该文件的位移量设置为文件长度加offset,offset可为正或负。
用r e a d函数从打开文件中读数据
#include <unistd.h>
ssize_t read(int feledes, void *buff, size_t nbytes) ;
返回:读到的字节数,若已到文件尾为0,若出错为- 1。
如r e a d成功,则返回读到的字节数。如已到达文件的尾端,则返回0。
用w r i t e函数向打开文件写数据。
#include <unistd.h>
ssize_t write(int filedes, const void * buff,
size_t nbytes) ;
返回:若成功为已写的字节数,若出错为- 1。
其返回值通常与参数nbytes的值不同,否则表示出错。w r i t e出错的一个常见原因是:磁盘已写满,或者超过了对一个给定进程的文件长度限制。
fcntl函数可以改变已经打开文件的性质。
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int fcntl(int filedes, int cmd, ... ) ;
返回:若成功则依赖于cmd(见下),若出错为- 1。
f c n t l函数有五种功能:
n 复制一个现存的描述符, 新文件描述符作为函数值返(c m d=F_DUPFD)。
n 获得/设置文件描述符标记,对应于filedes 的文件描述符标志作为函数值返回.(c m d = F_GETFD或F_SETFD)。
n 获得/设置文件状态标志,对应于filedes 的文件状态标志作为函数值返回。(c m d = F_GETFL或F_SETFL)。
n 获得/设置异步I / O有权(c m d = F_GETOWN或F_SETOWN)。
n 获得/设置记录锁(c m d = F_SETLK , F_SETLKW)。
#include <sys/types.h>
#include <unistd.h>
#include <fcnt1.h>
int fcnt1(int filedes, int cmd,... struct flock flockptr ) ;
struct flock 结构
ioctl 函数是I / O操作的杂物箱。不能用本章中其他函数表示的I / O操作通常都能用i o c t l表示。终端I / O是ioctl 的最大使用方面,主要用于设备的I / O控制。
#include <unistd.h> /* SVR4 */
#include <sys/ioctl.h> /* 4.3+BSD * /
int ioctl(int filedes, int request, . . . ) ;
返回:若出错则为- 1,若成功则为其他值
I/O处理的五种模型
① 阻塞I/O模型:若所调用的I/O函数没有完成相关的功能就会使进程挂起,直到相关数据到达才会返回。如:终端、网络设备的访问。
② 非阻塞模型:当请求的I/O操作不能完成时,则不让进程休眠,而且返回一个错误。如:open、read、write访问。
③ I/O多路转接模型:如果请求的I/O 操作阻塞,且他不是真正阻塞I/O,而且让其中的一个函数等待,在这期间, I/O还能进行其他操作。如:select函数。
④ 信号驱动I/O模型:在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动I/O。
⑤ 异步I/O模型:在这种模型下,当一个描述符已准备好,可以启动I/O时,进程会通知内核。由内核进行后续处理,这种用法现在较少
#include <sys/types.h>/* fd_set data type */
#include <sys/time.h> /* struct timeval */
#include <unistd.h> /* function prototype might be here */
int select (int numfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds, struct timeval * timeout) ;
返回:准备就绪的描述符数,若超时则为0,若出错则为- 1。