apue第三章 文件IO 笔记

主要有read write lseek close open.其中read write都是系统调用.

open或者creat会返回当前最小的文件描述符fd(>=0).0,1,2一般被系统占用.

creat只能以只写方式打开创建文件,如果创建后想写,只能creat,close,open.

close会关闭文件,并释放进程在文件上的所有记录锁.

当进程终止时,内核自动关闭所有打开文件.

每个被打开文件都有"当前文件偏移量",通常读写都会从文件偏移量开始.open时如果制定模式append就从文件末尾,否则从开始.

lseek将当前文件偏移量记录在内核,不引起IO操作.

下面看代码应用:"写空洞":

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "fcntl.h"
#include "string.h"
#include "sys/stat.h"

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(){
    int fd = creat("file.hole", FILE_MODE);

    if (fd < 0){
        printf("creat error\n");
        exit(1);
    }

    char buf1[] = "aqweqwe";
    char buf2[] = "ASDASDASD";


    int buf1len = strlen(buf1);
    if (write(fd, buf1, buf1len) != buf1len){
        printf("write error\n");
        exit(1);
     }

    if (lseek(fd, 1024, SEEK_SET) == -1){
        printf("lseek error\n");
        exit(1);
    }

    if (write(fd, buf2, strlen(buf2)) != strlen(buf2)){
        printf("write error\n");
        exit(1);
    }

    exit(0);
}

用od -l file.hole可以看到具体内容.顺便也几下 od这个命令,就是将文件内容dump出来.


3.7 read函数,这个函数日常使用还是挺频繁的.

ssize_t read(int fd, void* buf, size_t nbytes);

read返回读取的字节数.如果失败返回0;而且有可能返回的比想要读取的nbytes小,原因有以下几点:

1)读普通文件时,读到文件末尾,比如离末尾还要30bytes,却要读100bytes,当然只能返回30了,这时就不要读了,不然下回是0.

2)从终端读取,每次最多读一行;

3)从网络读取,由于缓冲结构可能会造成返回值小于要求读的字节数;

4)由于某信号造成中断,这时已经去了部分数据.

3.8 write

返回值与传入写入bytes应该一致,不然就是写入失败了.常见原因是:磁盘已满,或者超过给定进程的文件长度限制.

大多文件系统采用预读技术.当顺序读时,系统就会读入比要求多的数据.

3.10 文件共享

内核使用三种数据结构标示打开的文件:

1)在进程task_struct里有一个记录项,记录项里包含一章打开文件描述符表,每个fd占一项.与每个fd相关的是:a)fd标志,b)指向一个文件表项的指针.

2)内核为所用打开文件维护一章文件表,其中包含:a)文件状态标志,b)当前文件偏移量c)指向该文件v节点指针;

3)v节点结构.其中包含了 文件类型和对文件进行操作的各种函数指针.linux使用了i节点


如果两个进程分别打开了同一个文件,他们分别拿到了一个fd,各自维护文件表,但文件表却指向同一个i节点.


3.11 原子操作

write时如果加了a_append,unix就保证内核每次对文件写之前,都将进程当前偏移量设置到文件末尾,

传统的unix都在内核设置有缓冲区告诉缓存或者页面告诉缓存,大多数磁盘IO都通过缓存进行.采用延迟写来减少IO,但降低了文件更新速度.

fsync将修改过的块缓冲区排入写队列,然后返回,并不等待实际写磁盘结束.

通过被称为update的demon进程会周期性调用sync.保证了定期冲洗内核块缓冲区.

fsync要等待磁盘操作结束才返回,可用于数据库这样的程序,要求修改过的块立即写入.

3.14 fcntl可以改变已打开文件的性质.

3.15 ioctl 额,这个书上没讲什么,还是自己man吧


课后题

1.都是有缓冲机制的,比如延迟写.上面笔记也写到了;

2.实现与dup2功能相同函数,但不能调用fcntl 并有出错处理:

表示不会....

好了,该洗洗睡了.

明天开始第四章,顺便继续想想这几道课后题.



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值