前言
上一节:学习笔记——Linux的open、write、read、lseek、close函数
上一节学习了Linux的open、write、read、lseek、close函数,那么标准C函数fopen、fwrite、fread、fseek、fclose和他们有什么不同呢?该怎么用呢?
区别可以看看这里学习笔记——open和标准c库fopen的区别
下面我们用一个demo演示一下,其实和open等差别不大,参数有点变动。
fopen函数
fopen功能是打开文件。
#include <stdio.h>
//因为是标准C函数,所以只包含 <stdio.h>这个头文件
FILE *fopen(const char *path, const char *mode);
这个是比较常用的。
第一个参数是路径/文件名,比如“./file”
第二个是mode,mode的值是下面的这些参数
返回值;成功返回指向该文件的文件指针; 失败,返回NULL
// FILE *fdopen(int fd, const char *mode);
// FILE *freopen(const char *path, const char *mode, FILE *stream);
r:只读方式打开,文件必须存在
r+:可读写,文件必须存在
rb+:打开二进制文件,可以读写
rt+:打开文本文件,可读写
w:只写,文件存在则文件长度清0,文件不存在则建立该文件
w+:可读写,文件存在则文件长度清0,文件不存在则建立该文件
a:附加方式打开只写,不存在建立该文件,存在写入的数据加到文件尾,EOF符保留
a+:附加方式打开可读写,不存在建立该文件,存在写入的数据加到文件尾,EOF符不保留
wb:打开二进制文件,只写 wb+:打开或建立二进制文件,可读写
wt+:打开或建立文本文件,可读写
at+:打开文本文件,可读写,写的数据加在文本末尾 ab+:打开二进制文件,可读写,写的数据加在文件末尾
fread函数
fread功能:读数据到指定地址
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
void *ptr是数据的指针
size_t size是单个元素的字节数
size_t nmemb是读取的元素个数
FILE *stream是要读取的文件流
返回元素个数
fwrite函数
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
void *ptr是数据的指针
size_t size是单个元素的字节数
size_t nmemb是写入的元素个数
FILE *stream是要写的文件流
返回实际写入的数据项的个数
fseek函数
光标定位
int fseek(FILE *stream,long offset,int framewhere)
FILE *stream是文件流
long offset是偏移量
int framewhere是参数宏
SEEK_SET 既0 文件开头
SEEK_CUR 既1 文件当前位置
SEEK_END 既2 文件结尾
和lseek差不多
fclose函数
功能是关闭文件流,释放缓冲区。
int fclose(FILE*stream)
下面看看这个demo就都明白了。
demo1,操作函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
FILE *fp;
char *str = "handsome";
char *readBuf = NULL;
// char readBuf[128] = {0};
//open file
// FILE *fopen(const char *path, const char *mode);
fp = fopen("./file.txt","w+");
//write
//size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
fwrite(str,sizeof(char),strlen(str),fp);
//fwrite(str,sizeof(char)*strlen(str),1,fp);
fseek(fp,0,SEEK_SET);
//read
//size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
readBuf = (char *)malloc(sizeof(char)*strlen(str));
fread(readBuf,sizeof(char),strlen(str),fp);
//fread(readBuf,sizeof(char)*strlen(str),1,fp);
//print
printf("read data : %s\n",readBuf);
//close
fclose(fp);
return 0;
}
结果如下:
这里需要注意一下
fwrite和fread返回的int型的数据个数
假如
int nwrite = fwrite(str,sizeof(char),strlen(str),fp);
int nread = fread(readBuf,sizeof(char),strlen(str),fp);
此时的返回值是根据第三个参数判断的
我们写入数据,无论写多少、够不够长,都会按照我们给定的数值进行返回,比如第三个参数值是1,那么nwrite 就是1;第三个参数值是100,那么nwrite 就是100.
而读取不同,他会按照实际读取的数据个数进行判断,比如我们第三个参数是100,但是一共就读取了21个,那么只得返回21,因为不到100
demo2,写入结构体到文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Test{
int idata;
char cdata;
};
int main(){
FILE *fp;
struct Test data1 = {100,'a'};
struct Test data2;
//open file
fp = fopen("./file","w+");
//write
fwrite(&data1,sizeof(struct Test),1,fp);
//read
fseek(fp,0,SEEK_SET);
fread(&data2,sizeof(struct Test),1,fp);
//print
printf("read %d %c\n",data2.idata,data2.cdata);
//close
fclose(fp);
return 0;
}
看下结果:
总结
- open等函数和fopen等函数在操作上本质没有啥区别,但是不可以混用
- 注意fopen等函数的参数,和open不一致