unix环境高级编程之unbuffered io
2011-02-21 21:42
316 查看
五个文件io函数,open,read,write,lseek,close;
不带缓冲的io是指每个read,write函数都调用内核中的一个系统调用。它在多进程间共享资源,原子操作就变得很重要。
文件描述符:
对于内核而言,所有打开的文件都是通过文件描述符引用。他是一个费负整数,当打开或者创建一个文件,内核向进程返回一个文件描述符。
当读或者写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传给read或write。
0----标准输入 STDIN_FILENO
1-----标准输出 STDOUT_FILENO
2-----标准错误输出 STDERR_FILENO (定义在unistd.h中)
文件描述符限制在0-OPEN_MAX间
open函数
#include<fcntl.h>
int open(const char *pathname, int flag, /* mod_t mode */)
成功返回文件描述符,失败返回-1
flag有以下几种,可以用或运算构成flag参数
O_RDONLY 只读 0
O_WRONLY 只写 1
O_RDWR 读写 2
这三个常量中必须指定一个且只能指定一个,则下列常量是可选的。
O_APPEND 每次写追加到末尾
O_CREAT 若此文件不存在则创建它,使用此选项时需要指定第三个参数设置文件的访问权限
O_EXCL 如果同时指定了O_CREAT,而文件存在,则会报错。可用来测试一个文件是否存在,如果不存在则创建之,使测试和创建成为一个原子操作。
O_TRUNC 如果此文件存在,而且为只写或读写成功打开,则将长度截短为0
O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。
O_NOBLOCK 如果pahtname指的是一个FIFO,一个特殊块,或一个字符特殊文件,则此选项为文件的本次打开操作和后续的io操作设置非阻塞模式.
下面这三个操作是可选的
O_DSYNC 使每次write等待物理io操作完成,但是如果写操作并不影响读取到刚写入的数据,则不等待文件属性被更新。
O_RSYNC 使每一个以文件描述符作为参数的read操作等待,直到任何对文件同一部分进行的未决写操作都完成
O_SYNC 使每次写都等到物理io完成,包括有write操作引起的文件属性更新所需要的io。
creat函数
#include<fcntl.h>
int creat(const char *pathname, mod_t mod)
若成功则返回只写打开的文件描述符,否则返回-1
等价于
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mod)
由于unix早期版本中,open函数第二个参数只能是0,1或2,没有办法打开一个不存在的文件,因此需要creat创建一个新文件,现在open提供了O_CREAT, O_TRUNC,于是也不需要creat函数
close 函数
关闭一个打开的文件
#include <unistd.h>
int close(int filedes)
成功返回0,失败返回-1
lseek函数
没打开一个文件都会有一个与其相关联的“当前文件偏移量”,通常是一个非负整数,读写都是从当前文件偏移量开始,并使偏移量增加所读写的字节数。打开一个文件如果没有指定O_APPEND,则默认偏移量为0,这也是为什么写会覆盖原先的数据。
#include<unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
成功返回新的文件偏移量,失败返回-1
对offset的解释与参数whence有关
若whence是SEEK_SET,则将偏移量设置为据文件开始处offset字节。
若whence是SEEK_CUR, 则将偏移量设置为据当前值加上offset,offset可为正或负。
若whence是SEEK_END, 则将文件偏移量设置为文件长度加offset,offset可正可负。
若lseek成功则放回新的文件偏移量,失败返回-1
可用lseek(filedes, 0, SEEK_CUR)来测试文件是否可以设置偏移量。如果文件描述符引用的是FIFO,网络套接字,管道,则lseek返回-1,并将errno设置为ESPIPE
lseek便宜了记录在内核中,并不引起io操作,然后该偏移量用于下一个读或写操作。
偏移量大于当前文件长度将会引起文件空洞,文件空洞并不需要占用存储空间。
read函数
#include<unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
若成功则返回读到的字节数,读到文件尾则返回0,错误返回 -1
write函数
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
返回值与nbytes相同,否则表示出错。通常是磁盘已满,或者是超过一个给定进程的文件长度。
I/O效率
当bufsize为1024时io效率最好,可由试验得到。
文件共享
unix支持在不同的进程间共享打开的文件。
内核使用三种数据结构表示打开的文件。
1。每个进程在进程表中都有一个记录项。
2。内核为打开的所有文件维护一张文件表。
3。每个打开文件或设备都有一个v节点结构。
原子性操作
pread,pwrite
dup和dup2函数
用来复制一个现存的文件描述符
dup(filedes);等效于 fcntl(filedes, F_DUPFD, 0);
而调用dup2(filedes, filedes2)等效于close(filedes2); fcntl(filedes, FDUPFD, filedes2);
后一种情况并不完全等于close加上fcntl操作,因为dup2是原子操作
sync,fsync,fdatasync函数
传统unix实现在内核中并没有高速缓冲去,高速缓存,或页面高速缓存,大多数io都是通过缓冲进行。
#include<unistd.h>
int fsync(int filedes);
int fdatasync(int filedes);
成功返回0, 错误返回-1
void sync(void);
sync 只将所有修改过的块缓冲区排入写入队列,然后就返回,并不等待实际写磁盘操作结束。
通常称为update的系统守护程序会周期性的调用sync函数。这就定期的冲洗内核的块缓冲区。
fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束。可用于数据库类的程序,可以保证修改过的块立即写入到磁盘上。
fdatasync类似于fsync,但它只影响文件的数据部分。而数据外,fsync还会更新文件的属性。
fcntl函数
改变已经打开文件的性质。
#include <fcntl.h>
int fcntl(int filedes, int cmd, .../* int arg */);
返回值:若成功则依赖于cmd,出错返回-1
fcntl函数有五种功能:
1。复制一个现有的描述符 cmd=F_DUPFD
2。获得/设置文件描述符标记 cmd=F_GETFD/F_SETFD
3。获得设置文件状态标志 cmd=F_GETFL/F_SETFL
4。获得设置异步io所有权 cmd=F_GETOWN/F_SETOWN
5。获得/设置记录锁 cmd=F_GETLK, F_SETLK或者F_SETLKW
ioctl函数
ioctl函数是io操作的杂物箱,不能用本章中的其他函数表示的io函数都能用ioctl表示。
终端io是ioctl的最大 使用方面
#include <unistd.h>
#include <sys/ioctl.h>
#include <stropts.h>
int ioctl(int filedes, int request, ...);
出错返回-1,成功返回其他值。
/dev/fd
较新的系统度提供了/dev/fd目录,其目录项是名为0,1,2等文件,打开/dev/fd/n等效于复制描述符n,(假定描述符n是打开的);
相关文章推荐
- UNIX环境高级编程——标准I/O库函数和Unbuffered I/O函数
- UNIX环境高级编程——标准I/O库函数和Unbuffered I/O函数
- 【UNIX环境高级编程】文件 IO 操作 一 ( open | close | creat | lseek | write | read )
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
- UNIX环境高级编程(三)文件IO
- UNIX环境高级编程5.9二进制IO 输入输出流理解
- UNIX环境高级编程学习之第三章文件IO-文件写操作
- UNIX环境高级编程——标准IO-实现查看所有用户
- UNIX环境高级编程——标准IO-实现查看所有用户
- 3.UNIX 环境高级编程--文件 IO
- unix环境高级编程-文件IO
- unix环境高级编程笔记--高级IO
- UNIX环境高级编程学习之第三章文件IO-文件读操作
- UNIX环境高级编程——标准IO-实现查看所有用户
- (十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO
- Unix环境高级编程笔记:12、高级IO
- UNIX环境高级编程学习之第三章文件IO-文件读偏移操作
- UNIX环境高级编程---------文件IO
- unix环境高级编程-文件IO
- Unix环境高级编程:文件 IO 原子性 与 状态 共享