APUE读书笔记_CH3_文件I/O

鉴于buffer和cache其实是不同的东西,所以我不用书上所用的概念,buffer就是buffer,cache就是cahce。不明白的小伙伴传送过去看看:看过这两张图,就明白 Buffer 和 Cache 之间区别


一、I/O buffer

  1. 相对于ISO C语言定义的标准I/O,POSIX协议定义的是unbuffered I/O。
    所谓无缓冲就是指,直接调用system call (read,write)。

    • 对于c语言标准 I/O而言,要进行:
      数据–>fwrite/fread–>用户Buffer–>write/read–>内核缓冲区–>磁盘
    • 对于unix系统中的系统调用:
      数据–>write/read–>内核缓冲区–>磁盘
      可以看出来,其实unbuffered I/O其实还是有buffer的,只是我们看不见而已。

    看似c 标准IO,还多了几步,但就速度上来说,c库还是快很多的,请看原因:
    如果有过部分编程经验的话应该知道:每个系统调用到要从“用户态”,转换为“内核态”,这个过程是要消耗大量时间
    所以很多情况下程序员都需要想办法让系统调用的达到合理的次数。
    在用户态下设置buffer,并测试在自己电脑或服务器上,看看哪个size是最合适的。


二、一切皆是文件

  1. 我不知道在其他unix类中是什么情况,但是

    在linux中有一种思想:一切皆文件

linux把几乎所有的IO都虚拟成了一个文件,如果我要打印一份简历,我就向打印机fd写入数据。如果我要向远处的程序进行网络通信,我只需要向 socket fd写入我的数据。
2. 重要的文件描述符(File Descriptor,简称fd)

  • UNIX系统shell的三个重要文件fd(括号内数字可以直接替换符号常量):
    1.STDIN_FILENO(0)
    2.STDOUT_FILENO(1)
    3.STDERR_FILENO(2)

三、文件操作

  1. 常用文件操作函数

    int open(const char *path, int oflag, …);

    • int openat(int fd, const char *path, int oflag, …);
    • int close(int fd);
    • off_t lseek(int fd, off_t offset, int whence);
    • int fcntl(int fildes, int cmd, …);

2.比较难理解的就是:lseek的whence:是三个宏定义

新的文件偏移量off_t lseek(fd, 偏移距离 dis,SEEK_XXX)
设置当前距离为cur
设置文件长度为end(当打开方式为O_APPEND时,cur也等于end)
SEEK_SET:返回的新偏移量 = 0文件起始处 + dis
SEEK_CUR:返回的新偏移量 = cur + dis
SEEK_END:返回的新偏移量 = end + dis
  1. 通过对比标准I/O,我发现system call有个缺点就是写入二进制文件是需要自己控制编码。
    比如当我有一个结构体
struct Object
{
/*数据*/
};
/**
*当我的数据里本来就包含'\0'时,
*比如"ABCDJ12KLab\0JDLK\0djfBCjfh"(ps:这是一个完整的结构体,在内存中
*线性排列)。
*我现在必须把这个结构体完整的存入到磁盘中,于是:
*/

Object obj;
/*赋值obj*/
write(fd, (const char *)(&obj), sizeof(obj));
但是这次的system call write()仅仅写入到"ABCDJ12KLab\0"就停止了。
于是涉及到“序列化”的知识了。其实此处最简单的就是用标准I/O啊。 :)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值