一.I/O:一切实现的基础
分类:stdio 标准IO
sysio 系统调用IO
标准IO依赖与系统调用IO实现
在二者都可用的情况下,优先使用标准IO
原因:移植性好,合并系统调用
标准IO stdio:FILE类型贯穿始终
// fopen(); 打开文件
FILE *fopen(const char *path,const char *mode);
// 参数:文件路径,操作权限
// 返回值:成功:FILE类型的指针 -> 存放在“堆”
// 失败:NULL,设置errno number
// void perror(const char* s); 作用:在指定字段“s”后打印错误信息
// char *strerror(int errno); 作用:返回描述错误信息的字符串指针
// 文件打开数有上限
// 在不更改当前默认环境的情况下,程序默认打开三个流:stdin,stdout,stderr
// fclose(); 关闭文件
int fclose(FILE* fp);
// 参数:fopen() 返回的一个流
// 返回值:成功:0
// 失败:error
// fgetc(); 读取字符
int fgetc(FILE *stream);
// fputc(); 输出字符
int fputc(int c,FILE *stream);
// fgets(); 读取字符串
char *fgets(char* str,int size,FILE *stream);
// fgets()的正常结束:读到size-1 ->
// 读到'\n' ->
// fputs(); 输出字符串到指定流
int fputs(const char *str, FILE *stream);
// fread(); 二进制读取
size_t fread(void *ptr,size_t size,size_t,nmemb,FILE *stream);
// fwrite(); 二进制输出
size_t fread(const void *ptr,size_t size,size_t,nmemb,FILE *stream);
// printf()族函数;
int fprintf(FILE *stream,const char *format,...);
int sprintf(char *str,const char *format,...);
int snprintf(char *str,size_t size,const char *format,...); // 防止越界
int atoi(const char *str); // 将字符串转化为一个整型数
// scanf()族函数; -> 无法提前预测目标字符串的大小
int fscanf(FILE *stream,const char *format,...);
int sscanf(const char *str,const char *format,...);
// fseek(); -> 定位
int fseek(FILE *stream,long offest,int whence);
// 参数:需定位的流,偏移量,相对位置
// 相对位置:SEEK_SET(文件首),SEEK_CUR(文件的当前位置),SEEK_END(文件尾)
// 返回值:成功:返回0
// 失败:返回-1,设置error
// 用途:空洞文件的使用
// ftell(); -> 反应文件内指针的当前位置
long ftell(FILE *stream);
// rewind(); -> 重置文件内指针至文件首
void rewind(FILE *stream);
// fflush(); -> 强制刷新缓冲区
int fflush(FILE *stream);
缓冲区:大多数情况下是好事,合并系统调用
分类:行缓冲:换行时刷新,满的时候刷新,强制刷新[fflush()],(stdout是这样的,stdout是终端设备)
全缓冲:满的时候刷新,强制刷新(默认,只要不是终端设备)
无缓冲:如stderr,需要立即输出的内容
// setvbuf(); -> 修改缓冲区大小以及刷新模式
int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
// 参数:指定的流,分配给用户的缓冲,刷新模式,缓冲区大小
// mode:_IOFBF -> 全缓冲
// _IOLBF -> 行缓冲
// _IONBF -> 无缓冲
// getline(); -> 获取流中一行的内容
ssize_t getline(char **lineptr,size_t n,FILE *stream);
// 参数:存放内容的地址,前地址所指空间的大小,指定的流
// 返回值:成功:返回字符数
// 失败:-1
临时文件:
1.如何不冲突的创建临时文件
2.临时文件的及时销毁
// tmpnam(); -> 为一个临时文件起名,但不与创建文件同时进行
// 问题:在程序并发时,可能会造成文件名创建的混乱 <时间片轮转调度>
// 创建临时文件需要俩步,创建文字+创建文件 <危险操作>
// tmpfile(); -> 创建一个临时文件,匿名文件
// 解决了tmpnam所面临的问题
文件IO/系统调用IO:文件描述符fd贯穿始终
文件描述符的概念(int类型,本质是数组下标)
数组下标:0到1023 1024个(默认环境下)
文件描述符优先使用当前可使用范围内最小的
文件IO操作:
// open(); -> 打开文件,获取fd
int open(char *pathname,int flags);
int open(char *pathname,int flags,mode_t mode);
// 变餐实现,而非重载
// 参数:文件路径,文件选项
// flags:必须项+(文件的创建选项,文件的状态选项及以上状态的异或)
// close(); -> 关闭文件描符
int close(int fd);
// read(); -> 读
ssize_t read(int fd, void buf, size_t count);
// write(); -> 写
ssize_t write(int fd, void buf, size_t count);
// lseek(); -> 定位
off_t lseek(int fd,long offest,int whence);
// 参数:文件描述符,偏移量,相对位置
// 相对位置:SEEK_SET(文件首),SEEK_CUR(文件的当前位置),SEEK_END(文件尾)
// 返回值:成功:返回文件首到定位点的距离
// 失败:返回-1,设置error
将文件IO与标准IO的区别:
区别:响应速度(文件IO快,实时响应),吞吐量(标准IO大,缓存区)
标准IO与文件IO不可混用
标准IO合并以后统一调用系统IO
// fileno -> FILE *stream 转 int fd
int fileno(FILE *stream);
// fdopen -> int fd 转 FILE *stream
FILE *fdopen(int fd, const char *mode);
文件共享:多个任务共同操作一个文件或者协同完成任务
// truncate();/ftruncate(); -> 截短文件大小
int truncate(const char *path,off_t length);
int ftruncate(int fd, off_t length);
原子操作:不可分割的操作
作用:解决竞争和冲突
程序中的重定向:
// dup(); & dup2();
int dup(int oldfd); // 复制oldfd至当前可使用范围内最小的fd位
int dup2(int oldfd, int newfd); // 复制oldfd至newfd
同步:
// sync(); -> 全局催促,同步buffer和disk
void sync(void);
// fsync(); -> 同步文件的buffer和disk
int fsync(int fd);
// fdatasync(); -> 同步文件数据,不同步文件亚数据
int fdatasync(int fd);
管家级函数
// fcntl(); 管理文件描述符,文件描述符所变的魔术几乎都来源与该函数
int fcnt(int fd,int cmd,.../*arg*/);
// 参数:文件描述符,文件操作,操作所需的参数
// ioctl(); 管理设备相关的内容
int ioctl(int d, int request, ... /* arg */);
// 参数:要操作的设备,操作内容,操作所需的参数
/dev/fd/目录:虚目录,显示当前进程的文件描述符信息