文章目录
Unix I/O
Linux文件就是一个m个字节的序列,所有的IO设备(例如网络、磁盘和终端)都被模型化为文件,
而所有的输入和输出都被当作对相应的文件进行读和写。这种将设备优雅的映射为文件的方式,
允许Linux内核引出一个简单、低级的应用接口,称为 Unix I/O
这使得所有的输入和输出都能以一种统一且一致的方式来执行。
1.打开文件
一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备。
内核返回一个小的非负整数,叫做描述符<file descriptor>,用于标识这个文件。
内核记录有关这个打开文件的所有信息,应用程序只需记住这个描述符。
Linux shell创建的每个进程开始时都有三个打开的文件:(需头文件<unistd.h>)
0<->STDIN_FILENO
1<->STDOUT_FILENO
2<->STDERR_FILENO
2.读写文件
3.关闭文件
通知内核关闭该文件,内核会释放文件打开时创建的数据结构,并将该描述符恢复到可用
的描述符池中。无论一个进程因何种原因终止,内核都会关闭所有打开的文件并释放
他们的内存资源。
1.打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(char *filename, int flags, mode_t mode);
返回:
若成功则返回新文件描述符,失败返回-1。
返回的描述符总是在进程当前没有打开的最小描述符。
flags参数指明了进程打算如何访问这个文件:
可是以一个多个掩码的或。
O_RDONLY: 只读
O_WRONLY: 只写
O_CREAT : 如果文件不存在,就创建一个截断的(truncated)(空)文件。
O_TRUNC : 如果文件已存在,就截断它(长度被截为0,属性不变)
O_APPEND: 在每次写操作前,设置文件位置到文件的结尾
O_RDWR: 可读可写
mode参数指定了新文件的访问权限位。
2.关闭文件
close
函数关闭一个打开的文件
#include <unistd.h>
int close(int fd);
//返回: 若成功则为0,若出错则为-1
关闭一个已关闭的描述符会出错。
3.读和写文件
#include <unistd.h>
ssize_t read(int fd,void *buf,size_t n);
//read函数从描述符fd的当前文件位置拷贝最多n个字节到存储器buf
返回:若成功则为读的字节数,若EOF则为0,若出错为 -1.
ssize_t write(int fd,const void *buf,size_t n)
//write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置
返回:若成功则为写的字节数,若出错则为-1
ssize_t is long
size_t is unsigned long
read return:
return -1 :错误
return 0 :遇到EOF(end of file)
return >0:返回实际传送的字节数量
.
wrire return
return -1:错误
return >0:返回实际传送的字节数量
Short counts:不足值
比如规定max读200字节,实际文件只有100字节,那么第一次读的时候,会返回100,然后读进去。第二次读的时候会返回0,表示遇到EOF,即上次已经读到文件末尾了。
RIO Package
1.RIO无缓冲输入输出函数
rio_readn
和rio_writen
都会一直循环地读或写,直到不足值被妥善处理。
rio_readn
:从fd文件的当前位置最多传送n个字节到内存位置usrbuf,在遇到EOF只能返回一个不足值。
/*********************************************************************
* The Rio package - robust I/O functions
**********************************************************************/
/*
* rio_readn - robustly read n bytes (unbuffered)
*/
/* $begin rio_readn */
ssize_t rio_readn(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nread = read(fd, bufp, nleft)) < 0)