0731 IO进程基础
Part 1.梳理整理思维导图
一.什么是io函数
1.
i:input(外部设备到内存的过程)
2.
o:output(内存到外部设备的过程)
3.总结
io进程是(内存) 与(程序员和系统文件)之间的交互,例如我需要调用系统文件作为程序的数据,就需要input函数。我需要将数据保存到系统文件,则需要output函数
二.io的分类和区别
1.分类
1.标准io 2.文件io 3.阻塞io 4.非阻塞io 5.异步io 6.设备io
2.区别(标准io和文件io的区别)
1.标准io有缓冲区,文件io没有
2.标准io的读取速度快于文件io
3.标准io其实就是文件io的二次封装(加上缓冲区)
4.标准io不能与内核直接交互而文件io可以
5.标准io只能访问普通文件,而文件io能访问任意特殊文件
6.标准io属于库文件,可以在不同系统里用,移植性强
7.文件io是系统文件,移植性差,依赖系统
8.文件io需要借助文件描述符
9.标准io需要依赖流指针
10.文件IO是代码和文件系统之间的数据交互,标准IO是代码和程序员之间的数据交互
三。标准io函数
1.FILE
FILE属于一个结构体,里面包含各种io函数需要的流指针:
1.char* _IO_read_ptr; /* 当前的读指针*/
2.char* _IO_read_end; /* 读区域的结束指针 */
3.char* _IO_read_base; /* 读区域的起始指针 */
4.char* _IO_write_base; /* 写区域的起始指针 */
5.char* _IO_write_ptr; /* 当前的写指针*/
6.char* _IO_write_end; /* 写区域的结束指针*/
7.char* _IO_buf_base; /* 缓冲区的起始指针*/
8.char* _IO_buf_end; /* 缓冲区的结束指针 */
9.int _fileno; //文件描述符
2.fopen
a.作用
流式打开由pathname路径执行的文件(在程序中打开文件系统的文件)
b.格式
FILE *fopen(const char *pathname, const char *mode);
c.mode的类型
1.r :打开一个只读文件,如果文件不存在会报错
2.r+: 打开一个可以读写的文件,如果文件不存在会报错,打开的文件如果有内容会从头开始覆盖
3.w: 打开一个只读文件,如果文件不存在会创建文件,文件如果存在会清空文件
4.w+: 打开一个可读写文件,如果文件不存在会创建文件,文件如果存在会清空文件
5.a:打开一个只写文件,文件不存在创建,存在则从文件末尾开始写
6.a+:打开一个可读写文件,不存在则创建,存在若读则从头开始,若写则从尾开始
d.例子
FILE *p = fopen("./01","r+")//打开一个可读写文件,由FILE类型的指针p指向。
3.perror和strerror
a.作用
二者均是将io函数错误的返回值,翻译成英文输出
b.格式
perror:char *strerror(int errnum);
strerror:void perror(const char *s);
c.例子
perror:perror(”fopen error");//函数参数内为自己添加的注释
输出的例子为:fopen error:No such file
4.fclose
a.作用
关闭打开的文件
b.格式
int fclose(FILE *stream);
c.例子
fclose(p);//输入值是打开文件的流指针,返回类型为int型
5.fseek
a.作用
将文件内光标移动
b.格式
int fseek(FILE *stream, long offset, int whence);
c.where参数类型
SEEK_SET:文件的起始位置
SEEK_CUR:当前为止
SEEK_END:文件的末尾
d.例子
fseek(fp,0,SEEK_SET);//偏移到文件的起始位置fseek(fp,0,SEEK_END);//偏移到文件的末尾
6.fgets + fputs
a.作用
fgets:读取一个字符串的内容
fputs:写入一个字符串的内容
b.格式
fgets:int fputs(const char *s, FILE *stream);
fputs:char *fgets(char *s, int size, FILE *stream);
c.例子
p文件内的字符串:"hello world"fgets:fgets(arr,7,p);//"hello \0"只取6个,最后一个存'\0',存到p中
fgets(arr,12,p);//"world\n\0"会继续上一个字符串取,知道全部字符串结束或者遇到换行'\n',如果取的位数比总数多则全取,包括'\n',存到p中char arr[128] = "hello world";
fputs:fpuits(arr,p)//将arr中的字符串写入到p指向的文件
7.fprintf+fscanf
a.作用
读写不同的数据类型的
b.格式
fpromtf:int fprintf(FILE *stream, const char *format, ...);
fscanf:int fscanf(FILE *stream, const char *format, ...);
c.例子
fprintf:
fprintf(fp,"%d %.2f",100,3.14);//从fp指向的文件内连续获取%d类型和%f类型的两个数据
fscanf:
int a;
float b;
char c;
char str[128]="";
fscanf(fp,"%d %f %c %s",&a,&b,&c,str);//向p指向的文件连续存储%d %f %c %s类型的四个数据
Part 2.输入一个文件名,默认文件存在,实现这个文件的下载循环读取输入的文件,把读取的数据存到另一个文件中
#include<myhead.h>int main(int argc, const char *argv[])
{FILE *op = fopen("./01","r");if(NULL == op){ERR_MSG("op fopen error");}printf("op fopen success\n");FILE *ip = fopen("./02","r+");if(NULL == ip){ ERR_MSG("ip fopen error");}printf("ip fopen success\n");char arr[128] = "";while(1){memset(arr,0,sizeof(arr));if(NULL == fgets(arr,sizeof(arr),op))break;fputs(arr,ip);}rewind(ip);while(1){memset(arr,0,sizeof(arr));if(NULL == fgets(arr,sizeof(arr),ip))break;printf("%s",arr);}if(EOF == fclose(op)){ERR_MSG("op fclose error");}printf("op fclose success\n");if(EOF == fclose(op)){ERR_MSG("op fclose error");}printf("op fclose success\n");return 0;
}
Part 3.输入一个文件名,默认这个文件存在的,计算文件有几行,多大字节?
#include<myhead.h>int main(int argc, const char *argv[])
{char name[20] = "";printf("请输入你要计算的文件:\n");scanf(" %s",name);FILE *p = fopen(name,"r");if(NULL == p)ERR_MSG("p fopen error");printf("p fopen success\n");char arr[128] = "";int a = 0;printf("%s:\n",name);while(1){memset(arr,0,sizeof(arr));if(NULL == fgets(arr,sizeof(arr),p))break;printf("%s",arr);a++;}printf("总共%d行\n",a);fseek(p,0,SEEK_END);long size = ftell(p);printf("总共有%ld字节\n",size-a);if(EOF == fclose(p))ERR_MSG("p fclose error");printf("p fclose success\n");return 0;
}