1、概述:
(1)、unix类操作系统最重要的两个东东:进程和文件
(2)、大多数文件I/O用到的5个函数:open, close, read, write, lseek. 还有文件属性操作函数:dup, fcntl
(3)、unix类操作系统的文件I/O是不带缓存的I/O(unbuffered-I/O)
2、文件描述符(file
descriptor ,缩写fd)
(1)、unix类系统一般用0,1,2分别表示STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,来联系进程的标准输入,标准输出,和标准错误。
(2)、范围是0到OPEN_MAX
3、oepn: int open(const char *passname, int oflag, .../* , mode_t mode */);
(1)、oflag的值如下:
a、O_RDONLY, O_WRONLY, O_RDWR注意的是这三个东西不是各占一个二进制位,二是0, 1, 2,所以判断是只读,只写,读写时不能用 flag & O_RDONLY的方法,只能用flag == O_RDONLY。
b、O_CREAT、O_EXCL 两个一起用时,提供一个原子操作,当文件已存在时返回错误,否则创建文件;如果没有O_EXCL,则当文件存在时,忽略。用O_CREAT时候,需要有文件的mode_t参数。
c、O_NONBLOCK:此标志只适用于fifo,块设备文件和字符设备文件。
d、O_TRUNC:如果文件以只读或只写方式打开,则该文件长度截取为0;
e、O_SYNC:每一次write都等到物理操作完成后再返回。
4、close:int close(int fd);
注意:进程结束时候,内核会自动关闭该进程打开的所有文件,有很多程序利用了这一点。
5、lseek:off_t lseek(int fd, off_t offset, int whence);
参数whence的取值:SEEK_SET, SEEK_CUR, SEEK_END分标识文件的开头,当前指针,和结尾。
如果是SEEK_SET,则将当前位移量设置到文件开始处offset字节;如果是SEEK_CUR,则offset是相对于文件指针的当前位置;如果是SEEK_END,则offset相对于文件的末尾。后两种请况的offset可正可负。
返回新的文件位移量,注意某些 体统某种情况需要返回负值,因此这个测试应该是判断返回值是否为-1,而不是判<0
6、read: ssize_t read(int fd, void *buf, size_t len);
write:
ssize_t write(int fd, void *buf, size_t len);
注意read返回值:如成功,返回实际读入buf的字节数;如到达文件尾部,返回0;出错,返回-1
7、文件共享,在UNIX类操作系统中,文件可以供几个进程同一时间段访问。
每一个进程有一个进程记录项,而每个进程项当中有一子项是文件描述符数组。如下:
struct 进程记录项
{
...
struct 文件表[] //[]表示这是一个数组。
...
};
struct 文件表
{
文件当前的状态; //比如是只读,只写,读写,阻塞等等
文件当前的位移指针;
struct 文件信息 *; //也就是指向文件信息的指针
};
struct 文件信息
{
文件权限;
文件大小;
文件i节点;
...
};
每个进程有自己的打开的文件表数组和文件表结构,而打开的文件的文件信息是整个内核共同维护一份的。
8、原子操作举例:
比如:如果设置了O_APPEND标志,则进程在每次写文件之前,都把当前位移移到文件的末尾。
比如:O_CREAT | O_EXCL 标记和没有该标记时实现的功能相比。
9、dup函数:int dup(int fd);
在进程里拷贝一份进程描述符。但是文件表公用的。
10、fcntl:改变文件属性的函数。int fcntl(int fd, int cmd, .../* int arg */);
这个函数5个方面的用途:
a、复制文件描述符(cmd = F_DUPFD) 相当于 dup(fd);
b、文件描述符标志 (cmd = F_GETFD 或 cmd = F_SETFD)
c、文件状态标志
(cmd = F_GETFL 或 cmd = F_SETFL)
:F_SETFL可以设置的几个标志是:O_APPEND, O_SYNC, O_NONBLOCK,
O_ASYNC
d、异步I/O权限
(cmd = F_GETOWN 或 cmd = F_SETOWN)
e、记录锁
(cmd = F_GETTLK 或 cmd = F_SETTLK 或 cmd = F_SETLKW):高级I/O部分
11、/dev/fd目录:打开文件/dev/fd/n相当于复制描述符n