声明者不是原文,是读书笔记:
本章讨论了UNIX系统的文件I/O函数——打开文件、读文件、写文件等;涉及到的系统调用:open,read,write,lseek和close;
1)
#include<fcntl.h>
int open(const char *pathname,int oflag, ... /*mode_t mode */) ;
//返回的必定是最小未用文件描述符。
注意区分 oflag与 mode:
前者是打开标志是为了说明以什么方式打开文件(是读还是写抑或是添加等等);
后者是文件创建的时候设定的文件访问权限(用户,组,其它)(读,写,执行);对文件的操作都要有该mode验证相应用户的权限。
2)
#include<unistd.h>
off_t lseek(int filedes , off_t offset ,int whence);
//返回文件偏移量;
该函数有两个特殊用途:
确定所涉及的文件是否可以设置偏移量,如果文件引用一个管道、FIFO或网络套接字,则lseek返回-1;
当文件偏移量大于文件长度时,对该文件下次写将加长文件,主要必须是进行了一次写才会加长文件;
3)
#include<unistd.h>
ssize_t read( int filedes, void *buf, size_t nbytes );
ssize_t write(int filedes,const void *buf ,size_t nbytes);
size_t : 是 unsignde int ,一般用于指长度不可能为负数;
ssize_t : 是 signed int ,一般用于做函数返回值指长度,但是为-1时表示函数失败返回,故需为有符号类型;
我对文件读写过程的理解:
用户进程通过调用read 读请求进入内核先到磁盘高速缓存中找要读的部分是否已经在磁盘高速缓存中,若是则将内容复制到用户区。 若否则从该文件所在的磁盘读相应内容返回给用户区并存入磁盘高速缓存;(写过程与读过程类似);
大多数磁盘I/O都是通过缓冲进行。当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首是,才进行实际的I/O操作。这种输出方式称为延迟写。(此段为原文)
由于延迟写就带来了,文件的更新速度问题,为了保证文件与缓存中数据的一致性系统提供了如下三个函数。
(冲洗内核的快缓冲区)
int fsync(int filedes);
int fdatasync(int filedes);
void sync( void );
4)
本章的函数都被称为"不带缓冲“的I/O函数,所谓不带缓冲是指用户进程对这些函数不会自动带缓冲(文件标准IO是自动带的),其实这些函数的I/O还是要经过内核的块缓冲区。