目录
1.IO输入输出
2.Linux文件类型:
3.普通文件的操作
二进制文件操作
perror()
valgrind --tool=memcheck --leak-check=full filename
1.IO输入输出
操作对象是文件
2.Linux文件类型:
b block 块设备文件
按块扫描设备信息的文件
存储设备
c character 字符设备文件
按字符扫描设备信息的文件
d directory 目录文件
存放文件
- 普通文件
存放数据
图片、音视频、压缩包、文本文件
l link 链接文件
快捷方式
s socket 套接字文件
用来套接字通信
p pipe 管道文件
用来进程间通信
3.普通文件的操作
1.ASCII码文件
文件中所有的字符均为能够在终端上显示的字符
文本文件、程序.c
2.二进制文件
文件中存放数据的二进制形式
图片、音视频、压缩包
ASCII码文件是特殊的二进制文件
4.标准IO、文件IO
标准IO是库函数
文件IO是系统调用
系统调用:功能强大,应对复杂场景不够灵活
库函数:针对系统调用的封装,使用方便灵活
标准IO可以在Windows或者Linux平台使用
文件IO只能在Linux系统平台使用
5.标准IO:
getchar putchar scanf printf gets puts -> 标准IO
#include <stdio.h>
fopen/fclose
fgetc/fputc
fgets/fputs
fscanf/fprintf
fread/fwrite
fseek/rewind/ftell
6.从文件中读写数据的流程:
打开文件 -> 读写文件 -> 关闭文件
fopen fclose
fgetc/fputc 单个字符的读写
fgets/fputs 字符串的读写
fscanf/fprintf 格式化字符串的读写
fread/fwrite 二进制文件的读写
7.函数接口:
1.fopen
FILE *fopen(const char *pathname, const char *mode);
功能:
打开pathname对应的文件并与其建立一个文件流
参数:
pathname:要打开文件路径的字符串
mode:
r 只读 文件不存在报错,文件存在只读打开
r+ 读写 文件不存在报错,文件存在读写打开
w 只写 文件不存在创建,文件存在将文件内容清空,只写打开
w+ 写读 文件不存在创建,文件存在将文件内容清空,写读打开
a 追加只写 文件不存在创建,文件存在追加只写打开
a+ 追加写读 文件不存在创建,文件存在追加写读打开
返回值:
成功返回打开的文件流指针
失败返回NULL
2.fclose
int fclose(FILE *stream);
功能:
关闭文件,释放文件流指针
参数:
stream:文件流指针
返回值:
成功返回0
失败返回EOF(-1)
8.文件流:
1.具有方向性(读写)
2.具有连续性
3.具有顺序性
句柄:操作对象的一个抽象
valgrind --tool=memcheck --leak-check=full ./a.out
9.特殊的三个流:
stdin 标准输入流 从终端读取数据
stdout 标准输出流 向终端打印数据
stderr 标准出错流 向终端打印数据
getchar、scanf、gets 通过stdin来读取终端数据
putchar、printf、puts通过stdout来向终端输出数据
perror通过stderr来向终端输出数据
10.标准IO缓存(文件io是直接操作内核):
读写的时候才有缓存
缓存分为3类:
1.全缓存 4k
缓存区满刷新
刷新条件:
1.缓存区存满刷新(全缓存大小:4096)
2.fflush函数强制刷新
3.程序结束/fclose刷新
与文件建立的缓存
2.行缓存 1k
遇到\n刷新
刷新条件:
1.缓存区存满刷新(行缓存大小:1024)
2.遇到\n刷新
3.fflush函数强制刷新 fflish(stdout);
4.程序结束/fclose刷新
与终端建立的缓存 stdin stdout
3.不缓存
直接刷新ma
缓存区大小 0k stderr
人机交互、界面控制、出错处理
4.setvbuf
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
功能:
改变一个流的缓存类型
参数:
stream:文件流指针
buf:指定缓存空间的首地址,(不缓存就无首地址,大小也就是零)
缓存首地址,必须要先弄一个缓存空间(数组就可以就可以)
mode:
_IONBF 不缓存
_IOLBF 行缓存
_IOFBF 全缓存
size:
设定缓存区的大小
返回值:
成功返回0
失败返回非0
11.fputc
int fputc(int c, FILE *stream);
功能:
向流中写入一个字符
参数:
c:写入字符的ASCII码值
stream:文件流指针
返回值:
成功返回写入字符的ASCII码值
失败返回EOF
注意:
1.fputc只能写入一个字符,写入多个字符需要多次调用fputc
2.fputc只能写入字符
1.函数接口:
1.fgetc
int fgetc(FILE *stream);
功能:
从流中读取下一个字符
参数:
stream:文件流指针
返回值:
成功返回读到字符的ASCII码值
失败返回EOF
读到文件末尾返回EOF
2.fgetc/fputc与getchar/putchar的区别(没有区别)
char ch = 0;
ch = getchar();
ch = fgetc(stdin);
char ch = 'a'
putchar(ch);
fputc(ch, stdout);
3.fputs
int fputs(const char *s, FILE *stream);
功能:
向流中写入一个字符串
参数:
s:字符串首地址
stream:文件流指针
返回值:
成功返回非负数
失败返回EOF
4.fgets
char *fgets(char *s, int size, FILE *stream);
功能:
从流中读取一个字符串
参数:
s:存放字符串空间首地址
size:最多读取字符的个数
stream:文件流指针
返回值:
成功返回存放字符串空间的首地址
失败返回NULL
读到文件末尾返回NULL
gets和fgets区别:
1.gets没有给定最多读取字符的个数,有越界风险
fgets需要给定最多读取的字符个数,没有越界风险
2.gets会去掉从终端接收的\n字符,换成\0字符
fgets会保留从终端接收的\n字符,并在其末尾加入\0
puts和fputs
1.puts会在字符串末尾多打印一个\n字符
2.fputs不会在末尾多打印\n字符
二进制文件操作
1.函数接口:
1.fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
向流中写入nmemb个对象,每个对象size字节大小,在ptr指向的空间中
参数:
ptr:存放数据空间的首地址
size:每个数据对象的大小
nmemb:数据对象的个数
stream:文件流指针
返回值:
成功返回写入对象的个数
失败返回0
读到文件末尾返回0
2.fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
从流中读取nmemb个对象,每个对象size个字节,存放到ptr指向的空间中
参数:
ptr:存放读取内容空间首地址
size:读取对象的大小
nmemb:读取对象的个数
stream:文件流指针
返回值:
成功返回读到对象个数
失败返回0
读到文件末尾返回0
练习:
1.利用fread和fwrite完成将src.jpg图片内容拷贝到dst.jpg图片中
char tmpbuff[4096];
在读取之后最好能用他读取的返回个数进行写继续的写入(如下i),可以保证不会多写。
3.fprintf
int fprintf(FILE *stream, const char *format, ...);后面的逗号内容在终端上怎么打就可以在电脑上怎末大
功能:
将格式化字符串输出到stream指向的流中
printf
fprintf(stdout, );
4.fsancf
int fscanf(FILE *stream, const char *format, ...);
功能:
从流中读取格式化的字符串
2.流的定位:
1.ftell
long ftell(FILE *stream);
功能:
获得流的偏移量
2.rewind
void rewind(FILE *stream);
功能:
将流的偏移量重新设置到开头(直接会覆盖后面内容,而不是插入)
3.fseek
int fseek(FILE *stream, long offset, int whence);
功能:
设置流的偏移量
参数:
stream:文件流指针
offset:偏移量
> 0 向后偏移
< 0 向前偏移
whence:
SEEK_SET 文件开头
SEEK_CUR 文件当前位置
SEEK_END 文件末尾
统计文件大小
perror()
除了会打印括号里的字符还会打印程序出错的原因;
valgrind --tool=memcheck --leak-check=full filename
检测文件是否有内存泄漏