码迷,mamicode.com
首页 > 其他好文 > 详细

APUE读书笔记:File I/O

时间:2014-10-20 22:49:24      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   ar   使用   strong   sp   

文件描述符:

  1. 进程通过文件描述符来操作文件,文件描述符可以通过open, openat, creat系统调用返回;
  2. shell和其他应用默认打开标准输入(STDIN_FILENO),标准输出(STDOUT_FILENO),标准错误(STDERR_FILENO)三个文件描述符。

open和openat函数:

  1. 文件可以通过调用open或者openat函数打开或者创建;
  2.  新文件描述符使用最小未使用原则;
  3. TOCTTOU(time of check of time of use)的基本含义:程序是脆弱的,如果它调用两个基于文件的函数,并且后一个调用依赖于前一个调用的结果。因为这两个调用不是原子操作,在两个调用之间文件是可以被改变的,导致前一个调用的结果失效,错误发生。

creat函数:

  1. creat函数以只写的方式创建文件;
  2. creat函数完全可以用open函数代替:open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)。

lseek函数:
  1. 用于显式指定被打开文件的偏移量,返回当前文件的新偏移量;
  2. 测试标准输入是否可以seek:

bubuko.com,布布扣
 1 #include "apue.h"
 2 
 3 int main(void)
 4 {
 5     if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1) {
 6         printf("canot seek\n");
 7     }
 8     else {
 9         printf("seek OK\n");
10     }
11     exit(0);
12 }
View Code

  3. 由于文件当前偏移量可能为负数,lseek的返回值应该和 -1 比较,而不是测试是否小于0;
  4. 设置的当前文件偏移量大于文件长度时,文件中允许形成空洞,空洞不需要存储空间来存储;
  5. 在文件中创建一个空洞:

bubuko.com,布布扣
 1 #include "apue.h"
 2 #include <fcntl.h>
 3 
 4 char buf1[] = "abcdefghij";
 5 char buf2[] = "ABCDEFGHIJ";
 6 
 7 int main(void)
 8 {
 9     int fd;
10 
11     if ((fd = creat("file.hole", FILE_MODE)) < 0) {
12         err_sys("creat error");
13     }
14 
15     if (write(fd, buf1, 10) != 10) {
16         err_sys("buf1 write error");
17     }
18     /*offset now = 10*/
19 
20     if (lseek(fd, 16384, SEEK_SET) == -1) {
21         err_sys("lseek error");
22     }
23     /*offset now = 16384*/
24 
25     if (write(fd, buf2, 10) != 10) {
26         err_sys("buf2 write error");
27     }
28 
29     exit(0);
30 }
View Code

read/write函数:

  1. read函数被用于从打开的文件中读取数据,返回读取的字节数;
  2. write函数被用于向打开的文件中写数据,返回写入的字节数;

I/O效率:
  1. 利用缓冲将标准输入复制到标准输出:

bubuko.com,布布扣
 1 #include "apue.h"
 2 
 3 #define BUFFSIZE 4096
 4 
 5 int main(void)
 6 {
 7     int n;
 8     char buf[BUFFSIZE];
 9 
10     while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {
11         if (write(STDOUT_FILENO, buf, n) != n) {
12             err_sys("write error");
13         }
14     }
15     if (n < 0) {
16         err_sys("read error");
17     }
18 
19     exit(0);
20 }
View Code

  2. Linux ext4文件系统,块大小是4096,缓冲大小最佳值是4096。
文件共享:
  1. 内核使用三个数据结构表示打开的文件:

  • 每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述符的表,与每个文件描述符相关联的是: 文件描述符标志和指向文件表项的指针;
  • 内核维护一张所有已打开文件的文件表,每个文件表包括:文件状态标志,当前偏移量,指向文件V节点表项的指针;
  • 每个已打开文件(或者设备)都有一个V节点结构,Linux只有i节点;

 

bubuko.com,布布扣

原子操作:

  1. 任何需要多个函数的操作都不是原子操作;
  2. 调用pread相当于调用lseek后再调用read, 调用pwrite相当于调用lseek后再调用write,但是调用pread/pwrite是原子操作,且当前文件偏移量不更新;

dup和dup2函数:

  1. 一个已经存在的文件描述符可以用dup和dup2复制;
  2. dup返回最小可用文件描述符,dup2用fd2指定新文件描述符,如果fd2已经打开,则先关闭,如果fd2和fd1相等,则直接返回fd2不关闭它;
  3. dup/dup2总是清除新文件描述的close-on-exec标志;
  4. dup(fd)/fcntl(fd, F_DUPFD, 0),dup2(fd1, fd2)/close(fd2);fcntl(fd, F_DUPFD, fd2);

sync, fsync和fdatasync函数:

  1. sysc函数只将所有修改过的缓冲块排在写队列,然后返回,不等写磁盘发生;
  2. fsync只对fd单一文件起作用,它等磁盘写完成后再返回;
  3. fdatasync和fsync类似,但是它不同步更新文件属性,fsync同步更新;

 未完待续。。。。。

APUE读书笔记:File I/O

标签:style   blog   http   color   os   ar   使用   strong   sp   

原文地址:http://www.cnblogs.com/skycore/p/4035856.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!