不带缓冲区的IO和标准IO库
l 不带缓冲区的IO(unbuffered IO):
n open/read/write/close
n 每次read/write都调用内核的一个系统调用。这种IO都是针对文件描述符的,当打开一个文件时,返回一个文件描述符,然后该文件描述符用于后续的IO操作。
l 标准IO库:
n fopen/fread/fwrite/fclose/fgetc/fgets/ftell/fseek
n 围绕流进行。当用标准IO库打开或者创建一个文件时(得到FILE*),就使得一个流与一个文件关联。
n 标准库提供缓冲区的目的在于减少read/write系统调用的次数。
n 三种缓冲区:全缓冲,行缓冲,不缓冲(单个字符、stderr)
More about Unbuffered IO:
原子读写
l 文件可能被多个进程打开共享。
l 打开文件时,如果设置了O_APPEND标志,则会原子地执行以下两个操作:lseek到文件末尾并执行write。
l pread和pwrite函数允许原子地seek和IO。
调用pread相当于顺序调用lseek和read,并且:无法中断其lseek和read(两个操作共同成为一个原子操作),pread不会改变文件指针(pos值)。pwrite类似。
同步到磁盘
写文件时,内核常常将数据放在缓冲区中而不是立即写入(延迟写 delayed write)。如果需要手动同步到磁盘,则需要调用同步函数(sync/fsync/fdatasync)。
l sync函数:
void sync(void);
将所有修改过的块缓冲区排入写队列,然后返回,它并不等待实际写磁盘操作结束。
l fsync函数:
int fsync(int fd);
只针对fd指定的这个文件进行同步,fsync等待实际磁盘写操作完成才返回。
l fdatasync函数:
int fdatasync(int fd);
类似于fsync,但它只影响文件的数据部分(fsync同时也会更新文件的属性例如修改时间)。