嵌入式学习(day25)文件IO:open read/write close
文件IO:系统调用 Linux内核专门为应用层提供的文件操作方法
1、
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:打开文件并获得一个文件描述符。
参数:
pathname: 要打开的文件的文件名
flags: 打开方式
O_RDONLY: 只读方式
O_WRONLY: 只写方式
O_RDWR: 可读可写
O_CREAT: 创建文件
O_TRUNC: 清空文件
O_APPEND: 追加写
标准IO: 文件IO:
"r" O_RDONLY
"r+" O_RDWR
"w" O_WRONLY | O_CREAT | O_TRUNC, 0664
"w+" O_RDWR | O_CREAT | O_TRUNC, 0664
"a" O_WRONLY | O_APPEND | O_CREAT, 0664
"a+" O_RDWR | O_APPEND | O_CREAT, 0664
mode: 文件读写执行操作权限(当flag中有 O_CREAT 标志时,必须要增加 mode 操作权限)
rw-rw-rwx
111111111 ----> 0777
rw-rw-r--
110110100 ----> 0664
返回值:
成功:返回文件描述符。失败:-1
文件描述符:操作系统中已打开文件的标识符。
小的、非负的整形数据
范围:0-1023(总共 1024 个)
分配原则:最小未被使用原则
文件描述符泄露:已打开的文件,使用完时,未及时关闭。
操作系统已经打开的三个文件占用了 0、1、2 这三个文件描述符:
标准 IO: 文件 IO
FILE * int
stdin ----> 标准输入设备 ----> 0
stdout ----> 标准输出设备 ----> 1
stderr ----> 标准出错设备 ----> 2
2、ssize_t write(int fd, const void *buf, size_t count);
功能:向文件中写入数据
参数:
fd: 文件描述符
buf: 要写入的数据的首地址
count: 要写入的字节数
返回值:
成功:实际写入的字节数
失败:-1
3、ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读取数据
参数:
fd: 文件描述符
buf: 存储数据的空间首地址
count: 希望读取的字节数
返回值:
成功:实际读到的字节数
失败:-1
读到文件末尾:0
4、练习:使用文件IO分别实现cat功能和文件拷贝
//实现cat功能
#include <stdio.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc,const char *argv[])
{int fd =open(argv[1],O_RDONLY);if(-1 == fd){printf("open error\n");return -1;}char buff[1024] = {0};while(1){ssize_t cnt = read(fd,buff,sizeof(buff));if(0 == cnt){break;}else if(-1 == cnt){printf("read error\n");break;}write(1,buff,cnt);}close(fd);return 0;
}
//文件的拷贝功能#include <stdio.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc,const char *argv[])
{int fread =open(argv[1],O_RDONLY);int fwrite = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC,0664);if(-1 == fread || 1 ==fwrite){printf("open error\n");return -1;}char buff[1024] = {0}; while(1){ssize_t cnt = read(fread,buff,sizeof(buff));if(cnt <= 0){break;}write(fwrite,buff,cnt);}close(fread);close(fwrite);return 0;
}
5、文件定位函数:lseek:
off_t lseek(int fd, off_t offset, int whence);
功能:文件读写位置定位
参数:
fd: 文件描述符
offset: 偏移量(字节)
whence: 要偏移的相对位置
SEEK_SET: 文件开头位置
SEEK_CUR: 文件当前读写位置
SEEK_END: 文件末尾
返回值:
成功:返回当前读写位置到文件开头的偏移量
失败:-1
求文件大小:
off_t len = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET); // 文件读写位置复位。
6、标准IO、文件IO区别:
标准IO:
1. 属于C库函数,移植性强
2. 标准IO是系统调用的一次封装,增加了缓冲区,目的是提高数据读写的效率
3. 标准IO主要用在对普通文件的操作
文件IO:
1. 属于系统调用,只能用于Linux操作系统,移植性弱
2. 文件IO无缓冲区
3. 文件IO主要应用在对硬件的操作的,也可以操作普通文件
7、缓冲区:
(1) 行缓冲 1k(1024字节) ----> 人家交互界面、终端
缓冲区被刷新的方法:
1. 程序结束,自动刷新缓冲区
2. 遇到\n刷新
3. fflush()强制刷新
4. 缓冲区满刷新
(2) 全缓冲 4k(4096字节) ----> 文件缓冲区
缓冲区被刷新的方法:
1. 程序结束,自动刷新缓冲区
2. fflush()强制刷新
3. 文件关闭刷新
4. 缓冲区满刷新
(3) 无缓冲 0k --------> 出错信息对应的设备
stderr----> 无缓冲