C/C++的文件读写
程序员文章站
2024-03-17 11:47:16
...
在没有学习数据库之前,文件读写是学习C/C++初期遇到的比较麻烦的事情,其不仅要求多个标准库函数的配合使用,还要考虑到存储信息的方式(二进制文件/文本文件)。以下是我对于近期对于“文件读写”的经验总结。
二进制文件与文本文件的区别在于,数据存储时,是以什么形式存进去的(示例代码将在下面给出):
若你直接将数据写入文件中,那么数据是以二进制的形式存储,称为二进制文件;
若你是把数据先转换成字符串,再写入文件中,那么数据是以文本的形式存储,称为文本文件。
一、fopen的文件读写
首先,我们得了解ANSIC标准中C语言标准库中的文件读写函数(文本文件):
- 打开文件:FILE *fopen(const char *path, const char *mode);
- 读文件 :int fscanf(FILE *stream, const char *format, ...);
- 写文件 :int fprintf(FILE *stream, const char *format, ...);
- 文件结束:int feof(FILE *stream);
- 关闭文件:int fclose(FILE *fp);
以上一套文件读写函数的使用规则如下:
- 使用fopen函数,通过文件路径(path)和操作方式(读:"r",写:"w",添加:"a"),获取操作改文件的文件指针(FILE*);
//以读的方式,打开一个文本文件a.txt
FILE* ft_r = fopen("data/a.txt","r");
//以写的方式,打开一个文本文件a.txt
FILE* ft_w = fopen("data/a.txt","w");
- 使用fscanf函数,通过文件指针(FILE*)、由数据组成的字符串(“数据格式化……\n”)和数据的变量(数据……),取得文件中的字符串,并将其解析,给到各个变量。
//从文件a.txt中读出一行字符串,将其解析
fscanf(ft_r,"%d %s %s\n",&id,name,password);
- 使用fprintf函数,通过文件指针(FILE*)、有数据拼接的字符串(“数据格式化……\n”)和数据的变量(数据……),将拼接成的字符串存入文件中。
//向文件a.txt中,写入一行数据
fprintf(ft_w,"%d %s %s\n",id,name,password);
- 使用feof函数判断文件是否结束,调用若文件结束,则返回非零;若文件没有结束,则返回0。
//读取文件,直到结尾
while(!feof(ft_r))
{
//读文件
}
实例:fopen实现文本文件的一行一行的读写(代码片段)
bool Read_Data_T(tLink TL)
{
FILE* ft;
if((ft=fopen("data/AA_Teacher.txt","r")) == NULL)
{
//数据加载失败,程序结束
printf("老师数据为空\n");
exit(0);
}
//临时参数
tNode* tmp = (tNode*)malloc(sizeof(tNode));
while(!feof(ft))
{
fscanf(ft,"%d%s%s%s%hhd\n",&tmp->id,tmp->password,tmp->name,tmp->phone,&tmp->state);
Insert_tLink(TL,tmp->id,tmp->password,tmp->name,tmp->phone,tmp->state);
}
free(tmp);
fclose(ft);
printf("教师数据加载成功!\n");
return true;
}//读取老师信息
bool Write_Data_T(tLink TL)
{
FILE* ft;
if((ft = fopen("data/AA_Teacher.txt","w")) == NULL)
{
printf("教师数据无法存储\n");
return false;
}
tNode* node = TL->head;
tNode* tmp = node;
while(node != NULL)
{
fprintf(ft,"%d %s %s %s %hhd\n",node->id,node->password,node->name,node->phone,node->state);
tmp = node;
node = node->next;
free(tmp);
}
free(TL);
fclose(ft);
printf("教师数据存储成功!\n");
return true;
}//存入老师信息
二、open的文件读写
同理,我们得先了解系统函数的文件读写函数(二进制文件/文本文件):
- 打开文件:int open(const char *pathname, int flags, mode_t mode);
- 读文件 :ssize_t read(int fd, void *buf, size_t count);
- 写文件 :ssize_t write(int fd, const void *buf, size_t count);
- 关闭文件:int close(int fd);
以上一套文件读写函数使用规则如下:
- 使用open函数,通过文件路径(pathname)和操作方式(读:O_RDONLY,写:O_WRONLY,读写:O_RDWR,(如果不存在)创建:O_CREAT,清空:O_TRUNC),若创建需要添加一项文件权限,获取文件句柄。
//以读写的方式,打开文件a.txt,若不存在则创建
int fd = open("data/a.txt",O_CREAT|O_RDWR,0644);
- 使用read函数,通过文件句柄(fd)、存储的缓冲区、缓冲区大小,来读取文件数据。
//读取文件a.txt的数据
char buf[255] = {};
struct stu
{
int id;
char name[20];
char password[20];
}stu;
//文本文件
read(fd,buf,sizeof(buf));
//二进制文件
read(fd,&stu,sizeof(stu));
- 使用write函数,通过文件句柄(fd)、数据的缓冲区、缓冲区大小,来将数据写入文件。
//将数据写入文件a.txt
char buf[255] = “数据字符串!”;
struct stu
{
int id;
char name[20];
char password[20];
}stu{110,"keke","mima"};
//文本文件
write(fd,buf,sizeof(buf));
//二进制文件
write(fd,&stu,sizeof(stu));
实例:open实现二进制文件的读写(代码片段)
//发送一个文件,读文件再发送
while(1)
{
int ret = read(fd,&tmp,sizeof(Manager));
if(0 == ret) break;//确定文件结束
v_manager.push_back(tmp);
}
close(fd);
//接收一个文件,接收再写入文件
while(1)
{
if(v_manager.empty()) break;//确定数据全部写入完成
tmp = v_manager.back();
v_manager.pop_back();
write(fd,&tmp,sizeof(Manager));
}
close(fd);
三、C++的文件读写
同理的同理,我们还需要了解C++标准库内的文件读写函数(文本文件):
- 新建一个读数据流对象:ifstream 对象名(“文件路径”,ios::in);
- 新建一个写数据流对象:ofstream 对象名(“文件路径”,ios::out);
- 文件是否结束:数据流对象.eof(),若到文件结尾,返回true;若没到文件结尾,则返回false。
实例:使用C++的文件读写(代码片段):
//创建一个读数据流对象,并进行相关操作
ifstream input(pathname,ios::in);
for(int i=0;i<num1;i++)
{
input >> id >> name >> num2; //读取并解析
if(input.eof()) return; //确定文件读取完全
Employee* em = new Employee(id,name,num2/100,num2%100);
cout << em->getId() << " " << em->getName() << " " << em->getSex() << " " << em->getAge() << endl;
de->getV_employeep().push_back(em);
}
//创建一个写数据流对象,并进行相关操作
ofstream output(pathname,ios::out|ios::trunc);
while(!de->getV_employeep().empty())
{
Employee* em = de->getV_employeep().back();
output << em->getId() << " " << em->getName() << " " << (int)em->getSex()*100+em->getAge() << endl;
de->getV_employeep().pop_back();
delete em;
}
四、文件读写的功能
- 通过文件读写(二进制文件)实现唯一序号的获取功能:https://gitee.com/ZhongShengXueXi/codes/4pifys0qv7b19lxmzd8w330
- 待扩展……
上一篇: JUC Lock Condition实现精确通知唤醒
下一篇: ThreadLocal