APUE_第3章 文件I/O

本章主要讲打开一个文件,然后读写这个文件;

3.1 引言

底层的unix IO主要有6个函数:open, close, read, write, lseek, stat. 这6个函数都是系统调用,并不带缓冲区;
本章的函数都是不带缓冲区的, 不带缓冲是指每个read, write都是内核中的一个系统调用,在用户层没有缓冲区;
一旦涉及在多个进程之间共享资源, 就需要考虑原子操作;

3.2 文件描述符

文件描述符的变化范围是:0-OPEN_MAX;
所有的打开文件都是通过文件描述符引用的, 内核是向打开的进程返回文件描述符的;

3.3 open函数

int open(const char *pathname, int flag, .../*mode_t mode*/);

只有当创建新文件的时候, 才需要第三个参数;
flag的值:

  1. O_RDONLY
  2. O_WRONLY
  3. O_RDWR
  4. O_APPEND
  5. O_CREAT:如果文件不存在, 就创建文件
  6. O_EXCL:用于测试一个文件是否存在。与—O_CREAT一起使用时,如果测试结果是文件不存在在, 就创建文件;测试文件和创建文件是一个原子操作。
  7. O_TRUNC 将文件截断为0
  8. O_NONBLOCK:如果文件是FIFO, 块或是字符特殊文件, 则后续的IO访问操作都是非阻塞的,不能正常访问的时候返回错误;
  9. O_DSYNC 使每次write等待IO操作完成;
  10. O_RSYNC:使每一个以文件描述符作为参数的read等待, 直到多文件的同一部分的未决写操作完成;
  11. O_SYNC:使每次write都等待物理IO操作完成;
    open 返回的文件描述符一定是最小值的未使用描述符值;
    文件名和路径名截短
    如果NAME_MAX是14, 如果我们试图创建一个文件名包含15个字符的新文件。 系统会见那个15个字符的文件名字截断为14个字符,但是不会给出任何信息。BSD系统会给出出错状态,将errno设置为ENAMETOOLONG。
    如果NAME_MAX是14, 并且存在一个文件名就是14个字符的文件, 那么open(“filename”,…)函数就无法确定filename是否被截断过,也就无法确定该文件名的原始名字是什么;

3.4 creat函数

int creat(const char *filename, mode_t mode);
等效于
open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);

creat函数的不足之处就是以只写的模式创建文件,这样的文件不好去直接读取,现在可以使用下面代码进行文件创建:

open(pathname, O_RDWR | O_CREAT | O_TRUNC, mode);

3.5 close 函数

关闭一个文件, 内核会关闭文件的记录锁;

int close(int fd);

3.6 lseek函数

系统默认, 当打开一个文件的时候, 除非指定O_APPEND, 否则偏移量设置为0;调用函数lseek显示地设置文件的偏移量;

off_t lseek(int fd, off_t offset, int whence);

whence的值:
1) SEEK_SET:从文件开始处计算偏移量;
2) SEEK_CUR:从文件当前位置计算偏移量;
3) SEEK_END:从文件结尾处设置偏移量;
lseek函数返回的是新的文件偏移量, 可是使用下面函数得到文件当前的偏移量:

off_t curpos;
curpos = lseek(fd, 0, SEEK_CUR);

不能对管道、FIFO、网络套接字这类文件设置文件偏移量,如果lseek的参数fd是这三类文件, lseek函数会返回-1, 并将errno设置为ESPIPE;
lseek函数可能返回负数,所以对lseek函数返回值的检查, 不能使用小于0, 而是应该等于-1,如下:

if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1)	//正确
if(lseek(STDIN_FILENO, 0, SEEK_CUR) < 0)	//不正确

lseek仅仅修改内核中文件表的文件偏移量项, 并不引起任何IO操作。
文件偏移量可以大于文件的当前长度, 这种情况下, 对该文件的下一次写将加长该文件,并在文件中形成空洞;
文件中的空洞并不占有磁盘存储区, 当定

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值