学习APUE笔记2-文件IO

二.文件IO/系统调用IO

fd是在文件IO中贯穿始终的类型

 

1、文件描述符的概念(整形数  数组下标  文件描述符优先使用当前可用范围内最小的  作用域:当前进程)

 

2、文件IO操作:open close read write lseek

 

1>打开一个文件:int open(const char *pathname, int flags, ...);

返回值:成功,返回文件描述符; 出错, 返回-1.

pathname参数是要打开或创建文件的名字,flags参数:O_RDONLY 只读打开

       O_WRONLY 只写打开

       O_RDWR   读、写打开

       ......

2>关闭一个文件:int close(int fd);

返回值:成功,返回0; 出错, 返回-1.

关闭一个文件时还会释放该进程加在该文件上的所有记录锁.

 

3>读一个文件: ssize_t read(int fd, void *buf, size_t nbytes);

返回值:读到的字节数,若已到文件尾,返回0, 出错,返回-1.

fd表示读取那个文件, buf表示读取的字节放到buf中, nbytes表示读取的字节数.

 

4>写一个文件: ssize_t write(int fd, const void *buf, size_t nbytes);

返回值:成功,返回已写的字节数, 出错,返回-1.

fd表示要写入的那个文件, buf表示从buf中的内容读到fd当中, nbytes表示写入的字节数.

 

5>定位一个文件: off_t lseek(int fd, off_t offset, int whence);

返回值:成功,返回新的文件偏移量; 出错,返回-1.

参数fd表示要操作的文件,offset表示为偏移量,whence表示参照物(从哪里开始)

whence:SEEK_SET 偏移量设置为距文件开始处offset个字节;

SEEK_CUR 偏移量设置为当前值加offset个字节,offset可正可负;

        SEEK_END 偏移量设置为文件长度加offset个字节,offset可正可负。

没有单位的数值没有意义。

 

注意:od -c 查看文件中的空洞,ll -s 查看文件长度,du –s 查看文件占用磁大小

注意:当用 read 读 STDIN_FILENO 时候,如果要读的字符数为 x,终端中有字符 y 个,

如果 x>=y,那么 read 会读到 y 个字符,如果 x<y,那么 read 会读到 x+1 个字符,最后一个是'\n'.

 

3、文件IO与标准Io的区别

区别:响应速度&吞吐量

      文件IO 标准IO

面试:如何使一个程序变快?

用户体验上是吞吐量。

提醒:标准IO与文件IO不可混用。

转换:fileno  fdpoen

atrace ./ab 跟踪一个文件执行过程。

 

4、IO的效率问题

习题:将mycpy.c程序进行更改,将BUFSIZE的值进行放大,并观察进程所消耗的时间,

注意性能最佳拐点出现时的BUFSIZE值,以及何时程序会出现问题。

 

5、文件共享:多个任务共同操作一个文件或者协同完成任务

面试:写程序删除一个文件的第10行

补充函数:truncate/ftruncate.

 

6、原子操作:不可分割的单位

原子:不可分割的最小单位

作用:解决竞争和冲突

如tmpnam创建临时文件

 

7、程序中的重定向:dup dup2

 

1>复制一个现有文件描述符: int dup(int oldfd);

返回值:成功,返回新的文件描述符; 出错,返回-1.

复制后两个文件描述符指向同一个文件表项(struct file 结构体)实现文件的共享,同时写一个文件时是接续写.

 

2>复制一个新的描述符newfd: int dup2(int oldfd, int newfd);

返回值:成功,返回新的文件描述符; 出错,返回-1.

注意:返回的新描述符一定是当前可用的文件描述符的最小值;

注意:如果 newfd 已经被打开则会先关闭newfd(解除文件描述符与文件表项的链接),如果 newfd 和 oldfd 相等则该函数什么都不做;

注意:新描述符和旧的描述符各有自己的文件描述符标志,新文件描述符的 FD_CLOEXEC标志被清除。

注意:交叉写入时是接续写。

 

8、同步 sync fsync fdatasync

文件同步

把所有修改过的文件块刷到内核的写队列,并不等待真正的写到磁盘

针对内核

void sync(void);

 

和 sync 一样,不过这个函数只是针对于特定文件

void syncfs(int fd);

 

把 fd 描述文件的内容都刷到磁盘之后才返回

int fsync(int fd);

返回值:成功,返回0; 失败, 返回-1.

 

和 fsync 一样,不过这个函数只是刷新文件的数据部分,属性部分并不会因这个函数而刷新

int fdatasync(int fd);

返回值:成功,返回0; 失败, 返回-1.

 

9、函数 fcntl 和 ioctl

 

改变已经打开文件的属性:int fcntl(int fd, int cmd, ... /* arg */ );

这个函数可以改变/获取一个文件的文件描述符标志和文件状态标志

返回值:成功, 则依赖于cmd; 出错, 返回-1。

参数1表示要操作那个文件, 参数2表示要进行那个操作命令。

 

文件描述符标志:

现在的系统就一个 O_CLOEXEC,如果一个文件描述符标志中没有设置 O_CLOEXEC,那么在 exec 一个新程序的时候这个文件描述符依然有效,

否则这个文件描述符在 exec 的时候是关闭的,dup(2)复制的新文件描述符总是被清除 FD_CLOEXEC 标志.

 

文件状态标志:O_APPEND,O_RDONLY, O_WRONLY, O_RDWR 等标志,

在用 fcntl 设置文件状态权限是不能设置文件访问权限和文件创建的权限的,

比如 O_RDONLY, O_WRONLY, O_RDWR,O_CREAT, O_EXCL, O_TRUNC。

 

复制文件描述符:cmd=F_DUPFD/F_DUPFD_CLOEXEC

 

ioctl():设备相关的内容

int ioctl(int fd, int request, ...);

注意:这个和函数和底层的具体实现有关系

返回值:出错,返回-1; 成功,返回其他值。

 

10、/dev/fd/目录:虚目录 显示的是当前进程的文件描述符信息.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值