文件IO(input output 读写 )
===========
1.知识点概览
系统IO
open read write close lseek dup dup2 gets puts getchar putc
stat
标准IO
fopen fread fwrite fclose fprintf fscanf fgets fputs
对比系统IO和标准IO的区别
目录操作
opendir mkdir readdir closedir chdir
2. 在整个嵌入式课程体系中的作用
学习驱动,读写驱动的数据
linux中有句名言: linux中一切都是文件,文件IO可以对任何类型的文件进行读写操作
3. 岗位要求
嵌入式软件开发 ,应用开发--》必备知识点
系统IO
==============================
1. 相关的接口函数
(1)文件的打开或者新建文件 man 2 open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
返回值:成功 返回文件描述符(重点) 替身
失败 -1
参数:pathname --》你要打开的那个文件的路径名(linux中的路径)
flags --》系统定义的宏 O_RDONLY //只读 O_WRONLY //只写
O_RDWR //可读写
O_APPEND //追加的方式打开文件
O_CREAT //新建文件
O_EXCL //跟O_CREAT配合使用,如果新建的文件存在,就直接退出open,不存在就帮你新建
O_TRUNC //跟O_CREAT配合使用,如果新建的文件存在,就覆盖掉原来的文件
练习:
open("1.txt",O_CREAT|O_EXCL)
比如: 1.txt本来的权限444, 但是我使用O_WRONLY或者使用 O_RDWR
权限要保存一致
int open(const char *pathname, int flags, mode_t mode);
参数:mode --》你在新建文件的时候,可以给文件设置权限
0777 --》 八进制,表示权限
linux规定:
umask:权限掩码
新建的文件默认的权限是 666-umask 或者等价于 (666&(~umask))
以我的系统为例: 666-002=664 (最终你新建的文件权限)
(2) 文件的读取 man 2 read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值: 成功: 成功读取到的字节数(实际读取的字节数)
返回0:表示该文件已经读取完毕
失败: -1
参数: fd --》 你要读取的那个文件的文件描述符
buf --》通用类型指针,存放你读取到的文件内容
count --》你打算读取多少字节的数据
注意: count写100字节,但是read读取的是实际剩余的字节数
(3) 文件的写入 man 2 write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
返回值: 成功: 成功写入的字节数 count是多少,返回值就是多少
失败: -1
参数: fd --》 你要写入的那个文件的文件描述符
buf --》通用类型指针,存放你要写入的文件内容
count --》你打算写入多少字节的数据
注意: write的返回值,count写多少,返回值就是多少(万一buf中实际内容没有count这么多字节,凑够count字节,然后写入进去)
(4) 文件的关闭 man 2 close
#include <unistd.h>
int close(int fd);
(5) 判断文件是否存在
int access(const char *path, int amode);
返回值:文件存在 可读 可写 可执行 0
文件不存在 不可读 不可写 不可执行 -1
参数: path --》文件的路径名
amode --》R_OK 判断文件是否可读 W_OK 判断是否可写 X_OK 判断是否可执行 F_OK(判断文件是否存在)
(6) 修改权限
int chmod(const char *path, mode_t mode);
(7) 设置文件读写的偏移(类似windows的光标)
off_t lseek(int fildes, off_t offset, int whence);
返回值:成功 返回当前偏移位置距离文件起始位置的字节数
经典用法求文件的大小 lseek(fd,0,SEEK_END);
失败 -1
参数:fildes --》你要设置读写偏移的那个文件的文件描述符
offset --》你打算偏移多少字节
whence --》你打算从哪个位置开始偏移
SEEK_SET --》文件起始位置
SEEK_CUR --》当前位置
SEEK_END --》文件的末尾 lseek(fd,0,SEEK_END);
lseek(fd, -5 ,SEEK_SET); //无效的,起始位置往前挪动5个字节
lseek(fd, 5 ,SEEK_SET); //有效的,起始位置往后挪动5个字节
lseek(fd, -5 ,SEEK_CUR); //不确定,取决于往前挪动的时候有没有超过起始位置
lseek(fd, 5 ,SEEK_CUR); //有效的
lseek(fd, -5 ,SEEK_END); //不确定,取决于往前挪动的时候有没有超过起始位置
lseek(fd, 5 ,SEEK_END); //有效的
练习:
使用open read write close实现拷贝文件
一个小文件 1.txt 无法知道文件多大
一个大文件 1.bmp 通过主函数传参实现 无法知道文件多大
./main 1.txt 2.txt
./main 1.bmp 2.bmp
作业:
1. 设计一个拷贝文件的函数,该函数可以指定将源文件中从m到n这个范围的数据,拷贝到目标文件对应的m到n的位置, m,n从键盘输入
m --> 18
n -->100 表示 我要把1.txt中 第18到100字节的数据拷贝到2.txt中18到100的位置