文件IO(3)
今天继续学习文件I/O,主要介绍dup/dup2、sync/fsync/fdatasync、fcntl、ioctl等系统调用。
1.dup和dup2函数
1) 函数原型:
#include <unistd.h>
int dup(int filedes);
int dup2(int fildes.int filedes2);
2) 函数功能:
两个函数都用来复制一个现存的文件描述符。dup返回的新的文件描述符一定是当前可用文件描述符中的最小值。dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则先将其关闭,如果filedes等于filedes2,则dup2返回filedes2,而不关闭它。
注意:这些函数返回的新文件描述符与参数filedes共享一个文件表项。
2. sync、fsync、fdatasync函数
1) 函数原型:
#include <unistd.h>
void sync(void);
int fsync(int filedes);
int fdatasync(int fildes);
2) 函数功能:
传统的UNIX实现中,在内核设有高速缓存,大多数磁盘I/O通过缓冲进行。当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者内核需要重用该缓冲区以便存放其他数据时,再将该缓冲区排入输出队列,然后带其到达队首时,才进行实习的I/O操作。这种输出方式被称为延迟写。 延迟写减少了减少了磁盘读写次数,但却降低了文件内容的更新速度,使得欲写到文件中的数据在一段时间内并没有写到磁盘上,当系统发生故障时,这种延迟可能造成文件更新内容的丢失。为了保证磁盘上实际文件系统和缓冲区内容一致,UNIX提供了sync、fsync、fdatasync三个函数。
sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。
fsync函数只对文件描述符filedes指定的单一文件起作用,并且等待磁盘操作结束后返回。
fdatasync函数类似于fsync,但它只影响文件的数据部分,除数据外,fsync还同步更新文件的属性。
3. fcntl函数
1) 函数原型:
#include <fcntl.h>
#include <unistd.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
2) 函数功能:
fcntl函数有5个功能:
(1) 复制一个现有的描述符(cmd = F_DUPFD)
(2) 获得/设置文件描述符标记(cmd=F_GETFD/F_SETFD)
(3) 获得/设置文件状态标记(cmd=F_GETFL/SETFL)
(4) 或者/设置异步I/O标记(cmd=F_GETOWN/F_SETOWN)
(5) 获得/设置记录锁(cmd=F_GETLK/F_SETLK/F_SETLKW)
4.ioctl函数
1) 函数说明:
#include<sys/ioctl.h>
int ioctl(int,fd.int request,…)
ioctl用来控制特殊设备文件的属性,第一个参数fd必须是一个已经打开的文件描述符,第三个参数一般为char *argp,它随第二个参数request的不同而不同。参数request决定了参数argp是向ioctl传递数据还是从ioctl获取数据。