3.2 文件描述符
对于内核,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有或者创建一个新文件时,内核向进程返回一个文件描述符。当读写一个文件时,使用open或creat返回的文件描述符标识该文件,把他作为参数传递给read或write。
UNIX系统shell吧文件描述符0与进程的标准输入关联,1与标准输出关联,2与标准错关联。
文件描述符的范围0-OPEN_MAX-1。
3.3 函数open和openat
int open(const char*path,int oflag,...)
int openat(int fd,const char *path,int oflag,...)
oflag参数可用来说明此函数的多个选项。
详细解释参考man open。
由open和openat返回的文件描述符一定是最小的未使用的描述符数值。
3.4 函数create
相当于
open(path,O_CREAT|O_TRUNC|O_WRONLY,mode)
3.6函数lseek
每个打开的文件都有一个与其相关联的 当前文件偏移量。它通常是一个非负整数, 用以度量从文件开始处计算的字节数。
off_t lseek(int fd,off_t offset,int whence);
管道 或者套接字 不可以设置offset
3.7函数read
调用read函数从打开文件中读取数据。
int read(int fd,char *buf,unsigned nbytes);
3.8 函数write
写数据
ssize_t write(int fd,const void *buf,size_t nbytes)
实现文件复制
#include <iostream>
#include<fcntl.h>
#include<unistd.h>
using namespace std;
char buf[4096];
int main() {
int fd = open("//home//ubuntu//remote//apue//test//in.txt", O_RDONLY);
int fd2 = open("//home//ubuntu//remote//apue//test//in3.txt", O_CREAT | O_WRONLY);
int siz = 0;
siz = read(fd, buf, 4096);
while (siz!=0){
write(fd2, buf, siz);
siz = read(fd, buf, 4096);
}
return 0;
}
3.10 文件共享
内核使用3种数据结构表示打开文件。他们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
- 每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。
- 内核为所有打开文件维护一张文件表。每个文件表包括
- 文件状态标志
- 当前文件偏移量
- 指向该文件v节点表项的指针
3.11 原子操作
当要追加写文件时,如果未使用O_APPEND 标志。
则需要定位到文件尾然后再写文件,是两部操作。
会出现并发问题。
解决方法就是O_APPEND 操作,保证每次写的时候都会定位到文件末尾再写入。
3.12 函数dup和dup2
复制一个现有的文件描述符。
int dup(int fd)
int dup2(int fd,int fd2)