I/O库函数与系统调用
系统调用函数: open、read、 write、 IseekO、 close();
- I/O库函数
常见的打开方式:
r,rb 只读
w,wb 只写,如果文件不存在就创建
a,ab 追加,如果文件不存在就创建
r+,r+b,rb+ 读写方式打开
w+,w+b,wh+ 读写方式打开,文件不存在则创建
a+,a+b,ab+ 读和追加方式打开,文件不存在则创建
读文件
(b表示二进制文件)
size_t fread(void *ptr,size_t size,size_t n,FILE *stream)
stream:源文件
n:读取字段数
size: 每个字段的字节数
ptr:目标字符数组
返回实际读取的字节数
写文件
size_t fwrite(const void *ptr,size_t size,size_t n,FILE *stream)
ptr:源数组
n:字段数
size:字段的字节数
stream:目标文件
返回实际写入字段数
I/O库函数的算法
- fread算法
- 第一次调用时,fread()使用保存的文件扫描符fd发出 n=read(fd, fbuffer, BLKSIZE);系统调用,用数据块填充内部的fbuff[];
- 初始化fbuff[]指针、计数器和状态变量;
- 将数据复制到程序缓冲区;
- 若内部缓冲没有足够的数据,则使用read()继续填充内部缓冲区,并将数据从内部缓冲区复制到程序缓冲区;
- 复制完之后,更新内部缓冲区的指针、计数器,为下次read()做准备。
- fwrite算法
- 将数据写入内部缓冲区,调整缓冲区指针、计数器和状态变量;
- 若缓冲区满,则调用write()将缓冲区写入系统内核。
- fclose算法
- 关闭文件流局部缓冲区;
- 发出close(fd)系统调用关闭file结构体文件描述符;
- 释放file结构体,并将file指针重置为null。
I/O库模式
- 字符模式I/O
- int fgetc(FILE *fp);
- 该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
- int ungetc(int c, FILE *fp);
- 如果成功,则返回被推入的字符,否则返回 EOF,且流 stream 保持不变。
- int fputc(int c, FILE *fp);
- 如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。
- int fgetc(FILE *fp);
- 行模式I/O
- char *fgets(char *buf, int size, FILE *fp);
- 从fp中读取最多的为一行(以\n结尾)的字符。
- int fputs(char *buf,FILE *fp);
- 将buf中的一行写入fp中。
- char *fgets(char *buf, int size, FILE *fp);
- 格式化I/O
- 格式化输入
- scanf(char *FMT,&items);
- fscanf(fp, char *FMT,&items);
- 格式化输出
- printf(char *FMT,items);
- fprintf(fp,char *FMT,items)
- 格式化输入
- 内存中的转换函数
- sscanf(buf,FMT,&items);
- sprintf(buf, FMT, items);
- 其他I/O库函数
- fseek()、ftell()、rewind()
- 更改文件流中的读/写字节位置
- feof()、ferr()、fileno()
- 测试文件流状态
- fdopen()
- 用文件描述符打开文件流
- freopen()
- 以新名称重新打开现有的流
- setbuf()、setvbuf()
- 设置缓冲方案
- popen()
- 创建管道,复刻自进程来调用sh
- fseek()、ftell()、rewind()
文件流缓冲
每个文件流都有一个FILE结构体,其中包含一个内部缓冲区。对文件流进行读写需要遍历FILE结构体的内部缓冲区。文件流可以使用三种缓冲方案中的一种。
·无缓冲:从非缓冲流中写入或读取的字符将快单独传输到文件或从文件中传输。
例如,文件流 stderr通常无缓冲。到 I stderr的所有输出都会立即发出
·行缓冲:遇到换行符时,写人行缓冲流的字符以块的形式传输。
例如,文件流 stdout通常是行缓冲,逐行输出数据。
·全缓冲:写入全缓冲流或从中读取的字符以块大小传输到文件或从文件传输。这是文件流的正常缓冲方案。
通过 fopen(创建文件流之后,在对其执行任何操作之前,用户均可发出一个秒都会出现打印。
- setvbuf()
- 定义流 stream 应如何缓冲。
- int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
- fflush()
- 刷新流 stream 的输出缓冲区。
- int fflush(FILE *stream);
实践内容
最有收获的内容
在实践过程中熟练掌握了在Linux下的c文件的操作,并且对老师上课时一些不理解的地方也明白了。