C++的 I/O 流
本文把复杂的基类和派生类的作用和关系捋出来,具体的接口请参考相关文档
C++的 I/O 流相关的类,继承关系如下图所示
https://zh.cppreference.com/w/cpp/io

I / O 的概念:内存和外设进行数据交互称为 I / O ,例如:把数据写入磁盘,把数据显示到屏幕,把键盘的数据传到内存等等。
流的概念:可以理解为河水,有源头,有目的,按字节流动。按流传输时,不关心内容,格式,类型等等。
我们重点要掌握的是:输入输出流定义的全局对象 cout cin 等, 还有文件输入输出流,熟悉文件输入输出流相关接口。
成员变量
https://zh.cppreference.com/w/cpp/io/ios_base
我们要熟悉一下 ios_base 中维护的一些成员变量,首先就是流的打开方式
| 常量 | 解释 |
| std::ios::app | 每次写入前寻位到流结尾 |
| std::ios::binary | 以二进制模式打开 |
| std::ios::in | 为读打开 |
| std::ios::out | 为写打开 |
| std::ios::trunc | 在打开时舍弃流的内容 |
| std::ios::ate | 打开后立即寻位到流结尾 |
| std::ios::noreplace | 以独占模式打开 |
这里是不是有些奇怪,怎么打开流像打开文件一样?
以 Linux 系统为例,文件管理模块会把硬件设备全部抽象成文件:显示器,键盘,网卡等属于字符设备文件,存磁盘,u盘等属于块设备文件。经过虚拟文件系统对具体文件系统抽象后,上层会以统一的视角看待底层设备。
所以,这里的一层理解是:所谓的基于流的 I/O 可以理解为进程对某个文件的输入输出。比如,C++中最常用的 cin, cout, 就是对进程的0号文件描述符和1号文件描述符进行操作
文件有自己的打开方式,对应的,流也就有打开方式
视角再拉回来,ios_base 中的成员变量还有寻位相关的
| 常量 | 解释 |
| std::ios::beg | 流的开始 |
| std::ios::end | 流的结尾 |
| std::ios::cur | 流位置指示器的当前位置 |
还有流的状态
| 常量 | 解释 |
| goodbit | 无错误 |
| badbit | 不可恢复的流错误 |
| failbit | 输入/输出操作失败(格式化或提取错误) |
| eofbit | 关联的输出序列已抵达文件尾 |
输入输出操作
std::basic_streambuf 是输入输出操作的缓冲区
https://zh.cppreference.com/w/cpp/io/basic_streambuf
std::basic_streambuf 关联的缓冲区有两类:
1. 通过操作系统的API访问的实体(文件、TCP 套接字、串行端口、其他字符设备)
2.能解读成缓冲区的对象(std::vector, std::string等)
对于输入操作来说,该缓冲区称为获取区(进程从获取区拿数据)
对于输出操作来说,该缓冲区称为放置区(进程把数据放到放置区)
std::basic_ostream 提供输出操作
https://zh.cppreference.com/w/cpp/io/basic_ostream
标准库提供六个全局 basic_ostream 对象:
| 在标头 | |
| cout | wcout | 写入到标准 C 输出流 stdout (全局对象) |
| cerr | wcerr | 写入到标准 C 错误流 stderr,无缓冲 (全局对象) |
| clog | wclog | 写入到标准 C 错误流 stderr (全局对象) |
std::basic_istream 提供输入操作
https://zh.cppreference.com/w/cpp/io/basic_istream
标准库提供两个全局 basic_istream 对象:
| 在标头 | |
| cin | wcin | 从标准 C 输入流 stdin 读取 (全局对象) |
std::basic_iostream 继承了std::basic_ostream 和 std::basic_istream ,提供输入输出操作。
https://zh.cppreference.com/w/cpp/io/basic_iostream
为了理解 std::basic_streambuf std::basic_ostream std::basic_istream 我们看如下程序,下面程序中 MyStreamBuf 是自定义的缓冲区, 封装 std::string 对象。MyStreamBuf 继承了 std::streambuf 可以重写 std::streambuf 的虚函数,std::ostream 接受一个缓冲区 MyStreamBuf 作为参数实例化对象。
注:std::ostream , std::streambuf 是 std::basic_ostream , std::basic_streambuf 的别名
下面封装缓冲区是 重写 overflow 和 xsputn 两个虚函数,可以参考std::streambuf文档
#include <iostream>
#include <streambuf>
#include <string>// 自定义流缓冲区:将输出内容存储到字符串
class MyStreamBuf : public std::streambuf {
protected:std::string buffer_;// 处理单个字符输出virtual int_type overflow(int_type c) override {if (c != traits_type::eof()) {buffer_ += traits_type::to_char_type(c);}return c;}// 处理多字符输出virtual std::streamsize xsputn(const char* s, std::streamsize n) override {buffer_.append(s, n);return n;}public:const std::string& getBuffer() const { return buffer_; }
};int main() {MyStreamBuf buf; // 实例化自定义流缓冲区std::ostream myStream(&buf); // 构造ostream,使用自定义缓冲区myStream << "Hello World! " << 42 << std::endl; // 输出到流// 获取并打印缓冲区内容std::cout << "输出流里的内容是: " << buf.getBuffer();return 0;
}
文件的输入输出流
下面我们介绍 std::basic_fstream 。 std::basic_fstream 继承关系如下所示

基类我们前文已经介绍了,ios_base 维护必要的变量, basic_istream 提供输入操作, basic_ostream 提供输出操作。
std::basic_fstream 作为派生类,添加了一些文件相关的接口,可以参考文档
https://zh.cppreference.com/w/cpp/io/basic_fstream
下面写一个小程序,可以拷贝图片或视频
#include <iostream>
#include <fstream>
using namespace std;
int main() {// 打开源文件(二进制模式)fstream inFile("C:\\Users\\34497\\Desktop\\屏幕录制 2025-01-15 213832.mp4", ios::in | ios::binary); if (!inFile) {cerr << "无法打开源文件" << endl;return 1;}// 创建目标文件(二进制模式并清空内容)fstream outFile("C:\\Users\\34497\\Desktop\\destination.mp4", ios::out | ios::binary | ios::trunc); if (!outFile) {cerr << "无法创建目标文件" << endl;inFile.close();return 1;}// 使用缓冲区提高读写效率const int BUFFER_SIZE = 4096;char buffer[BUFFER_SIZE];// 循环读写文件内容while (inFile.read(buffer, BUFFER_SIZE)) {outFile.write(buffer, inFile.gcount());}// 处理最后一次读取的数据if (inFile.eof()) {// 写入剩余的有效数据outFile.write(buffer, inFile.gcount());}else {// 非EOF错误处理cerr << "文件读取过程中发生错误" << endl;inFile.close();outFile.close();return 1;}// 关闭文件流inFile.close();outFile.close();cout << "拷贝完成!" << endl; return 0;
}
相关文章:
C++的 I/O 流
本文把复杂的基类和派生类的作用和关系捋出来,具体的接口请参考相关文档 C的 I/O 流相关的类,继承关系如下图所示 https://zh.cppreference.com/w/cpp/io I / O 的概念:内存和外设进行数据交互称为 I / O ,例如:把数…...
寒假刷题Day22
一、2570. 合并两个二维数组 - 求和法 class Solution { public:vector<vector<int>> mergeArrays(vector<vector<int>>& nums1, vector<vector<int>>& nums2) {int i 0, j 0, n1 nums1.size(), n2 nums2.size();int tmp 0;…...
【PDF多区域识别】如何批量PDF指定多个区域识别改名,基于Windows自带的UWP的文字识别实现方案
海关在对进口货物进行查验时,需要核对报关单上的各项信息。对报关单 PDF 批量指定区域识别改名后,海关工作人员可以更高效地从文件名中获取关键信息,如货物来源地、申报价值等。例如文件名 “[原产国]_[申报价值].pdf”,有助于海关快速筛选重点查验对象,提高查验效率和监管…...
【大数据技术】本机PyCharm远程连接虚拟机Python
本机PyCharm远程连接虚拟机Python 注意:本文需要使用PyCharm专业版。 pycharm-professional-2024.1.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本地PyCharm远程连接虚拟机,运行Python脚本,提高编程效率。 注意: …...
Windows图形界面(GUI)-QT-C/C++ - Qt Combo Box
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 一、概述 1.1 基本概念 1.2 应用场景对比 二、核心属性详解 2.1 行为控制 2.2 显示配置 三、数据操作与访问 3.1 基础数据管理 3.2 高级数据访问 四、用户交互处理 4.1 信号处…...
数字化转型:概念性名词浅谈(第四讲)
大家好,本篇文章是在新年之际写的,所以在这里先给大家拜个年。 今天要介绍的名词为ETL: ETL,是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transfor…...
标题:市场波动中的价格趋势分析与策略优化
在市场投资中,价格的波动不仅是常态,更是影响投资决策的关键因素。市场价格的变化受多种因素影响,包括供需关系、政策调整、国际市场动态等。如何理解价格走势,并在其中寻找合适的交易机会,是投资者需要长期研究的课题…...
【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(四) -> 常见组件(一)
目录 1 -> List 1.1 -> 创建List组件 1.2 -> 添加滚动条 1.3 -> 添加侧边索引栏 1.4 -> 实现列表折叠和展开 1.5 -> 场景示例 2 -> dialog 2.1 -> 创建Dialog组件 2.2 -> 设置弹窗响应 2.3 -> 场景示例 3 -> form 3.1 -> 创建…...
Linux:文件系统(软硬链接)
目录 inode ext2文件系统 Block Group 超级块(Super Block) GDT(Group Descriptor Table) 块位图(Block Bitmap) inode位图(Inode Bitmap) i节点表(inode Tabl…...
深度学习系列--01.入门
一.深度学习概念 深度学习(Deep Learning)是机器学习的分支,是指使用多层的神经网络进行机器学习的一种手法抖音百科。它学习样本数据的内在规律和表示层次,最终目标是让机器能够像人一样具有分析学习能力,能够识别文字…...
如何抓取酒店列表: 揭开秘密
搜索酒店列表是一种强大的工具,可以从各种在线资源中收集有关住宿、价格和可用性的综合数据。无论您是要比较价格、分析市场趋势,还是要创建个性化的旅行计划,搜索都能让您有效地汇编所需的信息。在本文中,我们将介绍如何搜索酒店…...
深度剖析 C++17 中的 std::byte:解锁字节级编程新境界
文章目录 一、引入背景二、基本定义三、特性详解不可隐式转换为整型显式转换为unsigned char位运算支持字面量支持四、使用场景内存操作数据序列化与反序列化网络通信文件读写操作五、与其他数据类型的交互与字符类型的交互与整数类型的交互与指针类型的交互六、注意事项避免混…...
【多线程】线程池核心数到底如何配置?
🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 前置回顾2. 动态线程池2.1 JMX 的介绍2.1.1 MBeans 介绍 2.2 使用 JMX jconsole 实现动态修改线程池2.2.…...
三维空间全局光照 | 及各种扫盲
Lecture 6 SH for diffuse transport Lecture 7关于 SH for glossy transport 三维空间全局光照 diffuse case和glossy case的区别 在Lambertian模型中,BRDF是一个常数 diffuse case 跟outgoing point无关 glossy case 跟outgoing point有关 (Gloss…...
通过C/C++编程语言实现“数据结构”课程中的链表
引言 链表(Linked List)是数据结构中最基础且最重要的线性存储结构之一。与数组的连续内存分配不同,链表通过指针将分散的内存块串联起来,具有动态扩展和高效插入/删除的特性。本文将以C/C++语言为例,从底层原理到代码实现,手把手教你构建完整的链表结构,并深入探讨其应…...
Polardb三节点集群部署安装--附虚拟机
1. 架构 PolarDB-X 采用 Shared-nothing 与存储计算分离架构进行设计,系统由4个核心组件组成。 计算节点(CN, Compute Node) 计算节点是系统的入口,采用无状态设计,包括 SQL 解析器、优化器、执行器等模块。负责数据…...
java s7接收Byte字节,接收word转16位二进制
1图: 2.图: try {List list getNameList();//接收base64S7Connector s7Connector S7ConnectorFactory.buildTCPConnector().withHost("192.168.46.52").withPort(102).withTimeout(1000) //连接超时时间.withRack(0).withSlot(3).build()…...
挑战项目 --- 微服务编程测评系统(在线OJ系统)
一、前言 1.为什么要做项目 面试官要问项目,考察你到底是理论派还是实战派? 1.希望从你的项目中看到你的真实能力和对知识的灵活运用。 2.展示你在面对问题和需求时的思考方式及解决问题的能力。 3.面试官会就你项目提出一些问题,或扩展需求…...
基于springboot的体质测试数据分析及可视化设计
作者:学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”,支持远程部署调试、运行安装。 项目包含: 完整源码数据库功能演示视频万字文档PPT 项目编码࿱…...
java-重载与重写
介绍 在 Java 中,重载(Overloading) 和 重写(Overriding) 是两个重要的概念,它们都与方法有关,但它们的应用场景和行为完全不同。 通过理解重载和重写的区别,可以更好地设计类的继承…...
使用C++构建一个优先级队列
1.优先级队列的介绍 优先级队列是一种特殊的队列数据结构,它是队列,但又不完全是,因为它要将装载的数据进行优先级排序,找到一个最大或者最小优先级的元素,下一次出队列的元素就是这个元素,所以说它不完全是…...
linux驱动开发之字符设备与总线设备驱动模型的区别与联系
Linux驱动开发核心概念解析 1. 字符设备(Character Device) 定义与特点: 以字节流形式进行数据交换,适用于顺序访问的设备(如键盘、鼠标、串口)。 用户空间通过设备文件(如/dev/xxx࿰…...
AI deepseek对数据治理的影响
DEEPSEEK作为智能一款助手,在数据治理体系中具有深远的影响。它通过提供智能化、自动化和高效化的解决方案,推动企业在数据治理变革与领域的优化。以下是EPSEEK对数据治理体系影响的多角度分析: 一、战略层面:推动数据治理目标的…...
DeepSeek各版本说明与优缺点分析
DeepSeek各版本说明与优缺点分析 DeepSeek是最近人工智能领域备受瞩目的一个语言模型系列,其在不同版本的发布过程中,逐步加强了对多种任务的处理能力。本文将详细介绍DeepSeek的各版本,从版本的发布时间、特点、优势以及不足之处࿰…...
iOS 老项目适配 #Preview 预览功能
前言 iOS 开发者 最憋屈的就是UI 布局慢,一直以来没有实时预览功能,虽然swiftUI 早就支持了,但是目前主流还是使用UIKit在布局,iOS 17 苹果推出了 #Preview 可以支持UIKit 实时预览,但是仅仅是 iOS 17,老项目怎么办呢?于是就有了这篇 老项目适配 #Preview 预览 的文章,…...
在ubuntu22.04上先部署docker,再编译安装kamailio,附详细操作流程及docker和makailio的版本号
以下是在Ubuntu 22.04上部署Docker并编译安装Kamailio的详细操作流程,包含版本号信息: 一、部署Docker(版本:24.0.7) 更新系统包 sudo apt update && sudo apt upgrade -y安装依赖工具 sudo apt install -y ap…...
蓝桥杯试题:排序
一、问题描述 给定 nn 个正整数 a1,a2,…,ana1,a2,…,an,你可以将它们任意排序。现要将这 nn 个数字连接成一排,即令相邻数字收尾相接,组成一个数。问,这个数最大可以是多少。 输入格式 第一行输入一个正整数 nnÿ…...
C++常用拷贝和替换算法
算法简介: copy // 容器内指定的元素拷贝到另一容器replace // 将容器内指定范围的旧元素改为新元素replace_if // 容器内指定范围满足条件的元素替换为新元素swap //互换两个容器的元素 1. copy 功能描述: 将容器内指定范围的数据拷贝到另一容器中函…...
2024年12月 Scratch 图形化(三级)真题解析 中国电子学会全国青少年软件编程等级考试
202412 Scratch 图形化(三级)真题解析 中国电子学会全国青少年软件编程等级考试 一、选择题(共18题,共50分) 第 1 题 气温和对应的穿衣建议如下表所示,下列选项能正确给出穿衣建议的是?( ) A. …...
C# 中记录(Record)详解
从C#9.0开始,我们有了一个有趣的语法糖:记录(record) 为什么提供记录? 开发过程中,我们往往会创建一些简单的实体,它们仅仅拥有一些简单的属性,可能还有几个简单的方法,比如DTO等等…...
