玳瑁的嵌入式日记D17-08013(linux文件编程)
标准IO库
_fileno:
行缓存1024
遇到 '\n' 刷新,或者 fflush 刷新,或者 行缓存 溢出
全缓存4096
./a.out > 3.txt //输出重定向(4096)
./a.out <1.txt //输入重定向(1024)
无缓存
缓存设计原则
fseek ftell
int fseek(FILE *stream, long offset, int whence);
功能:
将stream指定的文件,从whence位置,定位到offset的位置
参数:
@stream --- 表示要定位的文件
@offset --- 偏移量
>0 //需要考虑参考点是否可以
<0
@whence --- 参考点
SEEK_SET //文件开头
SEEK_CUR //文件当前位置
SEEK_END //文件结尾
返回值:
成功 0
失败 -1 && errno会被设置
fseek(fp,0,SEEK_SET); //定位到开头
fseek(fp,0,SEEK_END); //定位到结尾
fseek(fp,100,SEEK_SET);//从头往后 偏移 100个字节
fseek(fp,-100,SEEK_SET);//从头往后 偏移 100个字节
说明:
文件往后偏移量 如果大于 文件本身是可以的
如果想占有存储空间,必须要有写操作
多出来的空间 --- 空洞 -- 用'\0'
创建空洞文件步骤:
1.定位 偏移
2.做一次写操作
baidu.downing //? ---临时文件 抢占磁盘空间
long ftell(FILE *stream);
获得stream对应文件的当前位置指示器的值
eg:
//文件大小
fseek(fp,0,SEEK_END);
long len = ftell(fp);
void rewind(FILE *stream);
功能,将文件定位到开头
练习:cp
标准IO 操作对象为 流指针(FILE *fp) 函数 :fopen
fgetc /fputc fgets/fputs fread / fwrite
fseek ftell rewind
细节:标准处理缓存 ,缓存机制(行缓存,全缓存,不缓存)
文件IO
文件IO 操作对象为 文件描述符 函数:open
read write
close
lseek
细节:文件描述符 就是一个编号 --代表打开文件
整型值
数值 --- 是一个非负值 >= 0
文件描述符 分配原则 --- 最小未使用 (不是顺序分配)
库函数和系统调用
库函数最终还是借助系统调用来实现
库函数
优点:
更丰富的功能
更优化的处理
方便高效
缺点:
安全性
系统调用
优点:
简单
安全性
缺点:
功能不够丰富
使用起来不大方便
open
#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_APPEND //追加 ---写
O_CREAT //创建
O_TRUNC //截断
@mode
表示创建文件的权限 --- 只有前面有O_CREAT时,才需要指定
0777
0666
返回值:
成功 返回文件描述符
失败 -1 &&errno
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
fopen(" 1.txt ","r") ------> open(" 1.txt ", O_RDONLY);
fopen(" 1.txt ","r+") ------> open(" 1.txt ", O_RDWR);
fopen(" 1.txt ","w") ------> open(" 1.txt ", O_WRONLY|O_CREAT|O_TRUNC,0666);
fopen(" 1.txt ","w+") ------> open(" 1.txt ", O_WRDR|O_CREAT|O_TRUNC,0666);
fopen(" 1.txt ","a") ------> open(" 1.txt ", O_WRONLY|O_CREAT|O_APPEND,0666);
fopen(" 1.txt ","a+") ------> open(" 1.txt ",O_RDWR|O_CREAT|O_APPEND,0666);
//流指针 <--------> 文件描述符
stdin 0
stdout 1
stderr 2
以上为系统默认打开
fd ------>文件标识符
练习:实现touch
read
ssize_t read(int fd, void *buf, size_t count);
功能:
从fd对应文件中读取数据,读count个字节,存放到buf指定的一块空间
参数:
@fd 就是要读取的文件
@buf 存放数据的空间
@count 要读取的字节数
返回值;
成功 读取到的字节数
失败 -1 &&errno
练习:
cat //open + read
注意:
read读到的数据,如果要当作字符串处理,
注意,需要手动处理成字符串
练习:cat // open+ read
write
ssize_t write(int fd, const void *buf, size_t count);
功能:
从buf中获得数据,写count个字节到 fd对应文件中
参数:
@fd 就是要写的文件
@buf 存放数据的空间
@count 要写入的字节数
返回值;
成功 写入的字节数
失败 -1 &&errno
练习: 用read 和 write实现文件拷贝
lseek
off_t lseek(int fd, off_t offset, int whence);
功能:
将fd定位到从whence开始的offset的位置
参数:
@fd 文件
@offset 偏移量
@offset --- 偏移量
>0 //需要考虑参考点是否可以
<0
@whence --- 参考点
SEEK_SET //文件开头
SEEK_CUR //文件当前位置
SEEK_END //文件结尾
定位开头:
lseek(fd,0,SEEK_SET);
定位到末尾
lseek(fd,0,SEEK_END);
返回值:
成功 返回从文库开头到当前定位处的偏移量
失败 -1 && errno
//获得文件大小
off_t len = lseek(fd,0,SEEK_END); //off_t //long int型
练习:
输入一个文件,创建一个 同样大小的空洞文件
fileno
int fileno(FILE *stream); //将FILE *fp 流指针转换为 fd
fd ---> FILE *fp
FILE *fdopen(int fd, const char *mode);
功能:
将 fd 对应文件打开 关联一个 FILE * 指针
fd = open("1.txt",O_RDONLY);
fdopen(fd,"r+");