C++文件操作基础 读写文本、二进制文件 输入输出流 文件位置指针以及随机存取 文件缓冲区以及流状态

一、写入文本文件

文本文件一般以行的形式组织数据。
包含头文件:#include <fstream>
类:ofstream(output file stream)
ofstream 打开文件的模式(方式):类内open()成员函数参数2.参数1是文件存储/创建路径

例如:fout.open(filename,ios::app);
对于 ofstream,不管用哪种模式打开文件,如果文件不存在,都会创建文件。
ios::out 缺省值:会截断文件内容。
ios::trunc 截断文件内容。(truncate)
ios::app 不截断文件内容,只在文件未尾追加文件。(append)

主要关注路径与文件名书写方法,推荐使用原始字面量和绝对路径,还有打开写入关闭等操作。

具体演示和步骤如下:

#include <iostream>
#include <fstream> // ofstream 类需要包含的头文件。
using namespace std;
int main()
{
// 文件名一般用全路径,书写的方法如下:
// 1)"D:\data\txt\test.txt" // 错误。
// 2)R"(D:\data\txt\test.txt)" // 原始字面量,C++11 标准。
// 3)"D:\\data\\txt\\test.txt" // 转义字符。
// 4)"D:/tata/txt/test.txt" // 把斜线反着写。
// 5)"/data/txt/test.txt" // Linux 系统采用的方法。
string filename = R"(D:\data\txt\test.txt)";
//char filename[] = R"(D:\data\txt\test.txt)";
// 创建文件输出流对象,打开文件,如果文件不存在,则创建它。
// ios::out 缺省值:会截断文件内容。
// ios::trunc 截断文件内容。(truncate)
// ios::app 不截断文件内容,只在文件未尾追加文件。(append)
//ofstream fout(filename);
//ofstream fout(filename, ios::out);
//ofstream fout(filename, ios::trunc);
//ofstream fout(filename, ios::app);
ofstream fout;
fout.open(filename,ios::app);
// 判断打开文件是否成功。
// 失败的原因主要有:1)目录不存在;2)磁盘空间已满;3)没有权限,Linux 平台下很常见。
if (fout.is_open() == false)
{
cout << "打开文件" << filename << "失败。\n"; return 0;
}
// 向文件中写入数据。
fout << "test1\n";
fout << "test2\n";
fout << "test3\n";
fout.close(); // 关闭文件,fout 对象失效前会自动调用 close()。
cout << "操作文件完成。\n";
}

二、读取文本文件

包含头文件:#include <fstream>
类:ifstream
ifstream 打开文件的模式(方式):
对于 ifstream,如果文件不存在,则打开文件失败。
ios::in 缺省值。

重点在于读取方法,具体演示如下:

#include <iostream>
#include <fstream> // ifstream 类需要包含的头文件。
#include <string> // getline()函数需要包含的头文件。
using namespace std;
int main()
{
// 文件名一般用全路径,书写的方法如下:
// 1)"D:\data\txt\test.txt" // 错误。
// 2)R"(D:\data\txt\test.txt)" // 原始字面量,C++11 标准。
// 3)"D:\\data\\txt\\test.txt" // 转义字符。
// 4)"D:/tata/txt/test.txt" // 把斜线反着写。
// 5)"/data/txt/test.txt" // Linux 系统采用的方法。
string filename = R"(D:\data\txt\test.txt)";
//char filename[] = R"(D:\data\txt\test.txt)";
// 创建文件输入流对象,打开文件,如果文件不存在,则打开文件失败。。
// ios::in 缺省值。
//ifstream fin(filename);
//ifstream fin(filename, ios::in);
ifstream fin;
fin.open(filename,ios::in);
// 判断打开文件是否成功。
// 失败的原因主要有:1)目录不存在;2)文件不存在;3)没有权限,Linux 平台下很常见。
if (fin.is_open() == false)
{
cout << "打开文件" << filename << "失败。\n"; return 0;
}第一种方法。
//string buffer; // 用于存放从文件中读取的内容。文本文件一般以行的方式组织数据。
//while (getline(fin, buffer))
//{
// cout << buffer << endl;
//}第二种方法。
//char buffer[16]; // 存放从文件中读取的内容。注意:如果采用 ifstream.getline(),一定要保证缓冲区足够大。
//while (fin.getline(buffer, 15))
//{
// cout << buffer << endl;
//}
// 第三种方法。
string buffer;
while (fin >> buffer)
{
cout << buffer << endl;
}
fin.close(); // 关闭文件,fin 对象失效前会自动调用 close()。
cout << "操作文件完成。\n";
}

三、读写二进制文件

包含头文件:#include <fstream>
类:ofstream(output file stream)
ofstream 打开文件的模式(方式):
对于 ofstream,不管用哪种模式打开文件,如果文件不存在,都会创建文件。
ios::out 缺省值:会截断文件内容。
ios::trunc 截断文件内容。(truncate)
ios::app 不截断文件内容,只在文件未尾追加文件。(append)
ios::binary 以二进制方式打开文件。
操作文本文件和二进制文件的一些细节:
1)在 windows 平台下,文本文件的换行标志是"\r\n"
2)在 linux 平台下,文本文件的换行标志是"\n"
3)在 windows 平台下,如果以文本方式打开文件,写入数据的时候,系统会将"\n"转换成
"\r\n";读取数据的时候,系统会将"\r\n"转换成"\n"。 如果以二进制方式打开文件,写和读都不会进行转换。
4)在 Linux 平台下,以文本或二进制方式打开文件,系统不会做任何转换。
5)以文本方式读取文件的时候,遇到换行符停止,读入的内容中没有换行符;以二制方式读取文件的时候,遇到换行符不会停止,读入的内容中会包含换行符(换行符被视为数据)。

6)在实际开发中,从兼容和语义考虑,一般:a)以文本模式打开文本文件,用行的方法操作它;
b)以二进制模式打开二进制文件,用数据块的方法操作它;c)以二进制模式打开文本文件和二进制文件,用数据块的方法操作它,这种情况表示不关心数据的内容。(例如复制文件和传输文件)d)不要以文本模式打开二进制文件,也不要用行的方法操作二进制文件,可能会破坏二进制数据文件的格式,也没有必要。(因为二进制文件中的某字节的取值可能是换行符,但它的意义并不是换行,可能是整数n 个字节中的某个字节)

fstream 打开文件的模式(方式):
对于 ifstream,如果文件不存在,则打开文件失败。

演示:(不熟悉网络通讯也可以尝试看看这个用语发送文件的简单成员函数,不用管有些没见过的函数,主要认识二进制数据块读出和写入。)需要注意write()和read()成员函数。

bool recvfile(const string &filename,const size_t filesize){
ofstream fout(filename,ios::binary);
if(fout.is_open()==false){cout<<"打开文件失败"<<endl;return false;}int onread=0;//每次调用fin.read()打算读取的字节数
int totalbytes=0;//从文件中已读取的总字节数
char buffer[4096];//每次存放读取数据的字节数while(true){//计算本次应接收数据的字节数
if(filesize-totalbytes>4096)onread=4096;
else onread=filesize-totalbytes;if(recv(buffer,onread)==false)return false;//接收文件数据fout.write(buffer,onread);//将接收的文件写入
totalbytes+=onread;//更新已接收文件字节数if(filesize==totalbytes)break;
}
return true;
}
 //向服务端发送文件内容
bool sendfile(const string& filename,const size_t filesize){
//以二进制的方法打开文件
ifstream fin(filename,ios::binary);
if(fin.is_open()==false){cout<<"打开文件:"<<filename<<"失败\n"<<endl;return false;}int onread=0; //每次调用fin.read()打算读取的字节数
int totalbytes=0;//从文件中已读取的总字节数
char buffer[4096];//每次存放读取数据的字节数while(true){
if(filesize-totalbytes>4096)onread=4096;//如果剩余数据字节数大于4096,则这次循环打算读取的数据字节数为4096
else onread=filesize-totalbytes;//否则就读取剩余数据的字节数fin.read(buffer,onread);//读取数据并存入bufferif(send(buffer,onread)==false)//向服务端发送数据return false;
totalbytes+=onread;//更新已读数据量
if(totalbytes==filesize)break;//如果全部数据读取完break
}
return true;
}

三、随机存取

1.fstream 类

fstream 类既可以读文本/二进制文件,也可以写文本/二进制文件。
fstream 类的缺省模式是 ios::in | ios::out,如果文件不存在,则创建文件;但是,不会清空文件原
有的内容。

普遍的做法是:
1)如果只想写入数据,用 ofstream;如果只想读取数据,用 ifstream;如果想写和读数据,用 fst
ream,这种情况不多见。不同的类体现不同的语义。
2)在 Linux 平台下,文件的写和读有严格的权限控制。(需要的权限越少越好)

2.文件的位置指针

对文件进行读/写操作时,文件的位置指针指向当前文件读/写的位置。不论读还是写所使用的类以及相关函数,文件位置指针有且只有一个,所有操作都在使用这一个指针,没有读指针和写指针这种说法。

1)获取文件位置指针

ofstream 类的成员函数是 tellp();ifstream 类的成员函数是 tellg();fstream 类两个都有,效果相
同。
std::streampos tellp();
std::streampos tellg();

2)移动文件位置指针
ofstream 类的函数是 seekp();ifstream 类的函数是 seekg();fstream 类两个都有,效果相同。
方法一:
std::istream & seekg(std::streampos _Pos);
fin.seekg(128); // 把文件指针移到第 128 字节。
fin.seekp(128); // 把文件指针移到第 128 字节。
fin.seekg(ios::beg) // 把文件指针移动文件的开始。
fin.seekp(ios::end) // 把文件指针移动文件的结尾。
方法二:
std::istream & seekg(std::streamoff _Off,std::ios::seekdir _Way);
在 ios 中定义的枚举类型:
enum seek_dir {beg, cur, end}; // beg-文件的起始位置;cur-文件的当前位置;end-文件的结尾位置。
fin.seekg(30, ios::beg); // 从文件开始的位置往后移 30 字节。
fin.seekg(-5, ios::cur); // 从当前位置往前移 5 字节。
fin.seekg( 8, ios::cur); // 从当前位置往后移 8 字节。
fin.seekg(-10, ios::end); // 从文件结尾的位置往前移 10 字节。


2)随机存取

是指直接移动文件的位置指针,在指定位置读取/写入数据。现在再来看:

ios::out 1)会截断文件;2)可以用 seekp()移动文件指针。
ios:trunc 1)会截断文件;2)可以用 seekp()移动文件指针。
ios::app 1)不会截断文件;2)文件指针始终在文件未尾,不能用 seekp()移动文件指针。
ios::ate 打开文件时文件指针指向文件末尾,但是,可以在文件中的任何地方写数据。
ios::in 打开文件进行读操作,即读取文件中的数据。
ios::binary 打开文件为二进制文件,否则为文本文件。
注:ate 是 at end 的缩写,trunc 是 truncate(截断)的缩写,app 是 append(追加)的缩写。

四、缓冲区及流状态

1.文件缓冲区

文件缓冲区(缓存)是系统预留的内存空间,用于存放输入或输出的数据。
根据输出和输入流,分为输出缓冲区和输入缓冲区。
注意,在 C++中,每打开一个文件,系统就会为它分配缓冲区。不同的流,缓冲区是独立的。
一般来说不用关心输入缓冲区,只关心输出缓冲区就行了。
在缺省模式下,输出缓冲区中的数据满了才把数据写入磁盘,但是,这种模式不一定能满足业务的
需求。
输出缓冲区的操作:
1)flush()成员函数
刷新缓冲区,把缓冲区中的内容写入磁盘文件。
2)endl  换行,然后刷新缓冲区。
3)unitbuf
fout << unitbuf;
设置 fout 输出流,在每次操作之后自动刷新缓冲区。
4)nounitbuf
fout << nounitbuf;
设置 fout 输出流,让 fout 回到缺省的缓冲方式。

2.流状态

流状态有三个:eofbit、badbit 和 failbit,取值:1-设置;或 0-清除。
当三个流状成都为 0 时,表示一切顺利,good()成员函数返回 true。

1)eofbit
当输入流操作到达文件未尾时,将设置 eofbit。
eof()成员函数检查流是否设置了 eofbit。
2)badbit
无法诊断的失败破坏流时,将设置 badbit。(例如:对输入流进行写入;磁盘没有剩余空间)。
bad()成员函数检查流是否设置了 badbit。
3)failbit
当输入流操作未能读取预期的字符时,将设置 failbit(非致命错误,可挽回,一般是软件错误,例
如:想读取一个整数,但内容是一个字符串;文件到了未尾)I/O 失败也可能设置 failbit。
fail()成员函数检查流是否设置了 failbit。

4)clear()成员函数清理流状态。
5)setstate()成员函数重置流状态。

五、End.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言sizeof 不是函数吗?

一、问题 sizeof 怎么⽤&#xff0c;它不是函数吗&#xff1f; 二、解答 sizeof 在 C 和 C 中不是一个函数&#xff0c;而是一个运算符。它在编译时计算其操作数所占用的内存大小&#xff0c;并返回一个大小&#xff08;字节数&#xff09;&#xff0c;这个结果是类型或表达式…

是用原生js创建红包雨效果

需求: 创建红包雨 答案: // 红包雨代码 开始 // 添加遮罩层 const addOverlay () > {const overlay document.createElement(div);overlay.className overlay;overlay.style.position fixed;overlay.style.top 0;overlay.style.left 0;overlay.style.width 100%;o…

DALL·E与NFT:开启艺术数字化的新篇章

DALLE与NFT概念 DALLE&#xff1a;这是一个由OpenAI开发的人工智能程序&#xff0c;它能够根据用户提供的描述生成相应的图片。DALLE的名字来源于艺术家萨尔瓦多达利&#xff08;Salvador Dal&#xff09;和迪士尼动画电影《瓦力》&#xff08;WALLE&#xff09;&#xff0c;这…

HarmonyOS应用开发者基础认证

华为开发者学堂 一、判断题 在Column和Row容器组件中&#xff0c;justifyContent用于设置子组件在主轴方向上的对齐格式&#xff0c;alignItems用于设置子组件在交叉轴方向上的对齐格式。&#xff08;正确&#xff09; 所有使用Component修饰的自定义组件都支持onPageShow&am…

Unity_使用Image和脚本生成虚线段

生成如图样式的虚线段 原理&#xff1a;使用Image做一条线段&#xff0c;这个方法的原理就是给固定的片元长度&#xff0c;对Image进行分割&#xff0c;把片元添加到一个列表中&#xff0c;然后循环对列表中的偶数位进行隐藏&#xff0c;也可以调整线段的宽度 缺陷&#xff1…

无公网IP实现远程访问MongoDB文件数据库【内网穿透】

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2…

支持向量机(SVM)详解

支持向量机&#xff08;support vector machines&#xff0c;SVM&#xff09;是一种二分类模型。它的基本模型是定义在特征空间上的间隔最大的线性分类器&#xff0c;间隔最大使它有别于感知机。 1、线性可分支持向量机与硬间隔最大化 1.1、线性可分支持向量机 考虑一个二分…

深入剖析C语言中的神秘字符——NULL

在编程的世界里&#xff0c;每一个字符都有其独特的意义。今天&#xff0c;我们将走进C语言的深处&#xff0c;探索那个被称为"NULL"的神秘字符。你是否曾对它感到困惑&#xff1f;它是如何定义的&#xff1f;又有什么作用&#xff1f;让我们一起揭开它的神秘面纱。 …

Disruptor挖坑MemoryAnalyzer来填

Disruptor挖坑MemoryAnalyzer来填 1、起因背景2、初步定位3、细化定位3.1、内存文件导出命令3.2、MemoryAnalyzer分析xxx.hprof文件 4、思考5、花絮 1、起因背景 博主练手写的并发项目订单服务出现了程序一直处于加载未完成的状态&#xff0c;电脑温度升高&#xff0c;CPU使用…

springboot125汽车资讯网站

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的125汽车资讯网站 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获…

springboot家乡特色推荐系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括家乡特色推荐的网络应用&#xff0c;在外国家乡特色推荐系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。家乡特色推荐系统采用java技术&#xff0…

UDS Flash刷写用例简单介绍

文章目录 1.Boot的功能1.1 目的1.2 功能 2.测试用例设计2.1 设计框架2.2 正向测试2.1.1 刷写流程2.1.2 重复刷写2.1.3压力刷写 2.3 逆向测试2.2.1 断电后刷写2.2.2 中断通讯后刷写2.2.3 篡改刷写数据2.2.4 修改软件校验数据2.2.5 修改刷写流程2.2.6 高负载刷写2.2.7 高低压刷写…

JuiceSSH结合内网穿透实现移动端设备公网远程访问Linux虚拟机

文章目录 1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? cpolarJuiceSSH 实现手机端远程连接Linux虚拟机(内网穿透,手机端连接Linux虚拟机) …

kafka为什么不支持读写分离?

kafka为什么不支持读写分离&#xff1f; 在kafka中&#xff0c;生产者写入消息&#xff0c;消费者读取消息的操作都是与 leader 副本进行交互的&#xff0c;从而实现的是一种主写主读的生产消费模型。kafka不支持读写分离&#xff0c;也就是主写从读。 读写分离有以下不足&am…

Linux下安装 Redis7

Linux下安装 Redis7 三、Linux下安装 Redis7【redis-7.2.4.tar.gz】3.1.下载redis的安装包3.1.1.手动下载Redis压缩包并上传【redis-7.2.4.tar.gz】3.1.2.wget工具下载redis-7.2.4.tar.gz 3.2.将安装包进行解压缩3.3.进入redis的安装包3.4.检查是否有gcc 环境3.5.编译和安装并指…

VS Code C++ 开发:入门和 IntelliSense 配置

你是否在满天星空下琢磨如何在 VS Code 中配置用于 C 开发的智能感知功能(IntelliSense)&#xff1f; 你是否想知道&#xff0c;有没有一种最简单的方法来运行你的 C 代码&#xff1f; 好消息是&#xff1a;我们在 C 扩展中添加了一些新功能&#xff0c;有了这些好东西&#xf…

Redis——关于它为什么快?使用场景?以及使用方式?为何引入多线程?

目录 1.既然redis那么快&#xff0c;为什么不用它做主数据库&#xff0c;只用它做缓存&#xff1f; 2.Redis 一般在什么场合下使用&#xff1f; 3.redis为什么这么快&#xff1f; 4.Redis为什么要引入了多线程&#xff1f; 1.既然redis那么快&#xff0c;为什么不用它做主数据…

解决Sublime Text V3.2.2中文乱码问题

目录 中文乱码出现情形通过安装插件来解决乱码问题 中文乱码出现情形 打开一个中文txt文件&#xff0c;显示乱码&#xff0c;在File->Reopen With Encoding里面找不到支持简体中文正常显示的编码选项。 通过安装插件来解决乱码问题 安装Package Control插件 打开Tool->…

matlab查看源代码

matlab函数源代码-查看 CtrlD 最简单方便的一种方法&#xff0c;鼠标划中函数名&#xff0c;按CTRLD即可打开函数的m文件

Windows本地如何部署Jupyter+Notebook并结合内网穿透实现远程访问?

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…