unix环境编程第三章笔记

3.2 文件描述符

文件描述符是一个非负整数,当打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,对于内核而言,所有打开的文件都是通过文件描述符引用。

3.3函数open和openat

原型:

int open (const char * path,int  oflag,......);
int openat (int fd, const char * path,int oflag , ......);//两函数的返回值若成功返回文件描述符,若出错返回-1.

参数path是要打开或创建的名字
oflag参数表示如何打开文件:
O_RDONLY //只读打开
O_WRONLY //只写打开
O_RDWR //读、写打开
O_APPEND //每次读写时都要追加到文件的底端
O_CREAT //若文件不存在则创建它,使用时open函数需要说明第三参数为mode(openat()函数需要说明第四参数为mode)

参数fd把两函数区分开来:
1.如果path指定的是绝对路径时,fd将被自动忽略,两函数无区别;
2..如果path指定的是相对路径时,fd参数指出了相对路径名在文件系统中的开始地址。
3.如果path指定的是相对路径时,fd参数具有特殊值AT_FDCWD 路径名在当前工作目录中获取,此时两者功能相似。
openat()函数存在意义:
1.可以使用相对路劲名打开目录中的文件,不仅仅只是打开当前工作目录。
2.避免TOCTTOU错误。
TOCTTOU错误: 如果有两个基于文件的函数调用,其中第二个调用依赖于第一个调用的结果,那么程序是脆弱的。因为两个调用并不是原子操作,在两个函数调用之间文件可能改变了,这样也就造成了第一个调用的结果就不再有效,是的程序最终的结果是错误的

creat 函数
int creat(const char * path , mode_t mode);
等价于
open(path,O_WRONLY | O_CREAT | O_TRUNC , mode )

3.6函数lseek

每一个打开文件都有一个与其相关联的“当前文件偏移量,当一个文件打开时除非指定O_APPEND选项,否则偏移量被设置为0;
off_t lseek(int fd, off_t offset, int whence);//若成功返回新的文件偏移量;若出错返回-1;
whence 有三种设置:

whence表示的内容
SEEK_SET偏移量为从文件开头处的offset个字节
SEEK_CUR偏移量为从当前偏移位置加offset个字节(offset可正可负)
SEEK_END偏移量为从文件的结尾加offset个字节(offset可正可负)

有的系统也把上述三个用0、1、2来表示。

文件空洞:文件的偏移量大于当前文件长度时,当下一次改文件执行写操作时,中间有空白。
文件中的空洞并不要求在磁盘上占用存储区。

od 命令//使用该命令观察文件的实际内容(文件空洞显示\0)
od -c 文件名//-c 表示以字符方式打印文件内容
\0表示文件空洞
注意:和cat命令的区别

3.7 read函数

int read (int fd, char * buf, unsigned nbytes);//从文件中读到buf中
返回读到的字节数,若读到结尾返回0,出错返回-1;

3.8 write 函数

size_t write (int fd, char * buf, unsigned nbytes);//从文件中读到buf中
返回读到的字节数,出错返回-1;

3.10文件的共享

进程打开文件:
(1)每一个进程在进程表中有一个记录项,记录项中包含一张打开文件描述符的表,每一个文件描述符包含:a.文件描述符的标志 b.指向一个文件表项的指针;
(2)每一个文件表项包含:
a.文件的状态标志;
b.当前文件偏移量;
c. v节点表项的指针;
(3)v节点包含:文件类型、对文件进行操作的各种指针,i节点;
i节点包含:文件的所有者、文件的长度、文件数据所在磁盘上的位置指针。

打开文件的内核数据结构

3.11原子操作

原子操作指的是由多步组成的一个操作。
原子操作的两个函数:
size_t pread(int fd, void *buf , size_t nbytes, off_t offset);
//相当于先调用lseek后调用read,返回读到的字节数,若已到文件结尾返回0,出错返回-1;
size_t pwrite(int fd, void *buf , size_t nbytes, off_t offset);
//相当于先调用lseek后调用write,返回已写的字节数,出错返回-1;

3.12函数dup和dup2

//复制一个现有文件描述符
//函数返回值若成功,返回新的文件描述符,出错返回-1;
int dup (int fd);
int dup2 (int fd, int fd2);//返回的文件描述符可以通过第二个参数”可用的文件描述符“指定。如果“可用的文件描述符“是打开状态,则会被关闭;如果”现存的文件描述符“和”可用的文件描述符“一样,则不会关闭
图3 内核dup后内核的数据结构
内核dup后内核的数据结构

更多关于dup和dup2函数的信息:
http://www.01happy.com/c-dup-dup2/

3.14函数fcntl

int fcntl(int fd, int cmd, …);
函数的功能:
1、复制一个已有的描述符(cmd =F_DUPFD或 F_DUPFD_CLOEXEC);
2、 获取/设置文件描述符标志(cmd=F_GETFD或F_SETFD);
3、 获取/设置文件状态标志(cmd=F_GETFL或F_SETFL);
4、 获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN);
5、 获取/设置记录锁(cmd=F_GETLK或F_SETLK、F_SETLWK);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值