shell
if 语句
case 语句
练习:输入文件名,若该文件存在则更改权限+x,若没有则声称该名字的目录及文件,并修改权限
练习:统计目录下普通文件和目录文件的数量
linux 文件类型:
b block /dev/sda 硬盘 -- 块设备文件
c char /dev/input/mouse1 鼠标 -- 字符设备文件
d directory 目录 目录 -- /home/linux
- regular 常规文件 常见文件 -- .txt .c .png
l symbolic link 符号连接 类似windows下快捷方式
p pipe 管道文件 进程间通信
s socket 套接字 进程间通信(网络)
文件编程
1.打开
fopen //file
FILE *fopen(const char *pathname, const char *mode);
功能:
流打开函数
打开 pathname指定的文件,并 关联一个流
参数:
@pathname 表示要打开的文件 //eg: 文件名 对应的字符串
@mode 模式
r 只读
r+ 读写
注意: 文件必须已经存在 ,不存在,则打开失败
w 只写
w+ 读写
注意: 如果文件存在,截断成0,不存在,则创建
a 追加的写
a+ 追加的读写
注意:
如果文件存在,则在末尾写
不存在,则创建
返回值:
成功 返回FILE *指针
失败 NULL 并 设置errno 用来表明错误原因
【stream】
1.流 是什么 ?
流 是 内存 和 硬盘直接 形成一个 数据通道
2.FILE *
流指针
关联到这个流上
代表这个流
3.fopen的作用
相当于 将 硬件上的文件 转换为 了 内存的的流指针
流指针
描述的是文件操作的这个动态的对象
4.errno 是系统设计错误码 的全局变量
errno = 2
perror("想要输出的字符串");
输出效果:
想要输出的字符串:错误原因
2.读写
fgetc/fputc //单个字符读写
int fgetc(FILE *stream);
功能:
从stream中读取字符
参数:
@stream 要读取的文件流指针
返回值:
成功 读取到的字符的ASCII码值
失败 EOF
注意:
文件结尾也是EOF
系统中,默认打开了三个文件,直接可以用
标准输入 --- stdin --- 关联到键盘
标准输出 --- stdout --- 关联到屏幕
标准出错 --- stderr --- 关联到屏幕
getchar() <=> fgetc(stdin);
fputc
int fputc(int c, FILE *stream);
功能:
将字符 c 写到 stream中
参数:
@c 就是要写的字符
@stream 要操作的文件
返回值:
成功 返回被写入的字符
失败 EOF
cat
(打印)
fgetc/fputc
fgets/fputs
fread/fwrite
3.关闭
fclose
int fclose(FILE *stream);
功能:
关闭流指针,并且刷新流中的数据到指定位置
// 关闭底层的文件描述符
返回值:
成功 0
失败 EOF
练习:
cp的命令
cp src.txt dest.txt
fgets/fputs
fgets //gets --- gets 编译器不推荐用,推荐使用fgets
char *fgets(char *s, int size, FILE *stream);
功能:
从stream 中读取一个字符串
将字符串,保存到s指定的size大小一块空间
参数:
@s 表示存储读取结果的 一块字符空间
@size 表示一次读取多少个字节
@stream 就是要读取的文件
返回值:
成功 返回 s
失败 NULL
注:
1. 读到文件结尾也返回NULL
出错也是NULL
【问题】 --- 那么如果返回值为NULL
到底是出错了,还是到达文件结尾了?
2. fgets 读取结束
(1) EOF会结束 //读到文件结尾 --- EOF并不存在文件中,只是到达结尾时的标志
(2) 遇到'\n' // '\n' 会被 读取到最终的 buffer中
(3) 读满size-1个
3.fgets 会自己在 buffer中最后一个字符的后面 加 '\0' --- 处理成字符串
4.fgets 比 gets 更安全
可以指定读取多少个字节的数据
fgets 更推荐使用
练习;
fgets 实现 cat
fputs
int fputs(const char *s, FILE *stream);
功能:
将s中的字符串,输出到 stream对应文件中
参数:
@s 要输出的字符串的地址
@stream 要输出到的文件
返回值:
成功 非负值
失败 EOF
注意:
fputs 不会自动输出一个 '\n'
puts //自动会输出一个 '\n'
fputs输出结束的条件 ---是遇到 '\0'
注意:
fgets 和 fputs 实现拷贝文件
对于二进制文件 --问题很大
二进制文件中 存储大量的 '\0'
fgets读取没有问题
但是fputs是要输出字符串
而字符串遇到 '\0' 就结束
fread/fwrite
//按对象读写
//二进制读写函数
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
从指定的文件中stream读取nmemb个元素,每个元素size大小的 这么多个数据,
存放到ptr指定的一块空间
参数:
@ptr 存储数据的空间的首地址
@size 单个元素的大小
@nmemb 多少个元素
@stream 要读取的流指针
返回值:
成功 返回读取到的对象个数
失败 0
到达结尾返回0
用途:
用来处理 文件中 操作对象 固定单一这种
结构体
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
将ptr所在空间的额 nmemb个大小为size的元素,写到stream对应的文件中
参数:
@ptr 存储数据的空间的首地址
@size 单个元素的大小
@nmemb 多少个元素
@stream 要写的的流指针
返回值:
成功 返回写入的对象个数
失败 0
注:
fread 和 fwrite配合用时
int ret = fread(buf,sizeof(int),10,fp);
fwrite(buf,sizeof(int),ret,stdout); //成功读取多少个就输出多少个
练习:
实现 cat
练习:
fread / fwrite 实现cp
feof////ferror
int feof(FILE *stream); //检查是否到达文件结尾
int ferror(FILE *stream);//检查是否出错
fprintf snprintf
int printf ( const char *format, ...);
int fprintf (FILE *stream, const char *format, ...);
fprintf(stdout,"%d:%d:%d\n",year,month,days);
fprintf(fp,"%d:%d:%d\n",year,month,days);
int sprintf (char *str , const char *format, ...);
int snprintf(char *str , size_t size, const char *format, ...);
snprintf(str,sizeof(str)"%d:%d:%d\n",year,month,days); //把输出结果处理成字符串 存放到str