我们继续学习Linux系统编程,我们书接上文。
复制文件描述符
我们都知道,文件描述符是找到每个打开文件的关键,我们也可以复制已经存在在进程中的文件描述符,对其进行操作。
dup()
调用复制一个打开的文件描述符,并返回一个新描述符,二者都指向同一个打开文件表表项。而且系统会保证新描述符一定是编号值最低的未用文件描述符。
#include <unistd.h>
int dup(int oldfd); //成功返回新的文件描述符失败返回-1
复制后的文件描述符与之前的文件描述符公用一个打开文件表表项,说以其两个文件的偏移量、文件状态标志等都是共享的。
dup2()
函数和dup()
函数类似,不过dup2()
函数允许用户使用第二个参数指定将文件描述符复制到一个指定的文件描述符上
int dup2(int oldfd,int newfd);
文件同步
进程进行写操作,每次将输入的内容写入内核的缓冲区内,当缓冲区被填满时将缓冲区的内容写到磁盘上。由于文件的写操作会因为缓冲的原因时输出延时,所以在一段时间内,会导致内存中的文件内容和磁盘上的文件内容不一致。为了避免这种情况,用户可以指定系统在缓冲区并未填满的情况下将文件内容回写到磁盘上,这种操作叫做文件同步。
#include<unistd.h>
int fsync(int fd);
int fdatasync(int fd); //返回值:若成功,返回0;若出错,返回−1
void sync(void);
sync只是将所有修改过的块缓冲区排入写队列,然后就返回,它并
不等待实际写磁盘操作结束。该函数能够加快文件同步速度,但是并不能保证真正的文件同步。
fsync函数可以确保文件的实际写出,该函数会阻塞知道修改的盘块写完后才返回,成功返回0,出错返回-1。
datasync函数类似于fsync,但它只影响文件的数据部分。而除数据
外,fsync还会同步更新文件的属性。
控制文件 fcntl()函数
我们还可以对一个已经打开的文件的属性进行修改,或者得到该文件中的某些属性;该函数可以看做时文件操作的一个集合,几乎所有的属性操作都可以通过调用fcntl()
实现
#include <fcntl.h>
int fcntl(int fd,int cmd,```);
参数
- 第一个参数
fd:表示需要进行属性的文件描述符(已经打开的文件) - 第二个参数
cmd:表示fcntl()函数的可执行的命令,每一个命令代表一个不同的功能如下
fcntl()函数的命令 | 该命令的功能 |
---|---|
F_DUPFD | 复制文件描述符 |
F_GETFD/F_SETFD | 获得/设置文件描述符标志 |
F_GETFL/F_SETFL | 获得/设置文件状态标志 |
- 第三个参数
fcntl()的第三个参数,其根据第二个参数的不同而不同,一般都是设置型的命令需要用到第三个参数,如- F_DUPFD:复制的新文件描述符
- F_SETFD:要设置的新的文件描述符
- F_SETFL:要设置的新的文件状态标志
返回值
函数的返回值也和参数所选择的命令有关,一般都是获取信心型的命令有返回值,如
- F_DUPFD : 返回复制的文件描述符
- F_GETFD : 返回文件描述符的标志
- F_GETFL : 返回文件的状态标志
- 其余的命令成功返回0,失败则都返回-1
通过 fcntl () 函数获取/设置已打开的文件属性
// 得到文件的flag属性
int flag = fcntl(fd, F_GETFL);
// 添加新的flag 标志
flag = flag | O_APPEND;
// 将更新后的falg设置给文件
fcntl(fd, F_SETFL, flag);
网友评论