c++怎么将一个大型文件的内容完全反向写入另一个文件【进阶】

陌磊君_9536

陌磊君_9536

2026-04-10

533人浏览

原创

不能直接用 std::reverse 处理大文件,因其需随机访问迭代器并全量加载内存,2GB 文件易触发 bad_alloc;应采用流式字节级反转,从末尾逐字节读写,注意 UTF-8 字符边界、换行符及 BOM 破坏问题。

c++怎么将一个大型文件的内容完全反向写入另一个文件【进阶】

为什么不能直接用 std::reverse 处理大文件

因为 std::reverse 要求随机访问迭代器,且必须把整个文件内容加载进内存——一个 2GB 的文本文件会直接触发 std::bad_alloc 或让程序卡死。真正的“反向写入”必须流式处理,跳过内存瓶颈。

核心思路:从文件末尾逐块倒读 + 正向写入缓冲区

关键不是“把文件倒过来”,而是“按字节逆序输出”。需用 seekg 定位到末尾,每次向前读固定大小(如 64KB),但注意:UTF-8、换行符、多字节字符边界会让简单倒读出错。所以实际要分两步:

  • 先用 seekg(0, std::ios::end) 获取文件总长度 file_size
  • 从 file_size - 1 开始向前遍历每个字节,但遇到 UTF-8 多字节字符开头(0xC0–0xF7)时,得回退直到找到合法起始字节(避免截断字符)
  • 更稳妥的做法是:只做**字节级反转**(不考虑编码),适用于二进制文件;若处理文本,应先确认源文件是纯 ASCII 或明确指定为单字节编码(如 ISO-8859-1)

实际可用的 C++ 实现(支持 GB 级文件)

以下代码绕过 C++ iostream 的缓冲缺陷,用 read() + write() 原生系统调用风格(Windows 用 CreateFile/ReadFile,Linux/macOS 用 open/pread),避免 seekg 在大文件上的性能抖动:

#include <fstream>
#include <sys> // Linux/macOS
// Windows: #include <windows.h><p>void reverse_file(const char<em> input_path, const char</em> output_path) {
std::ifstream in(input_path, std::ios::binary);
in.seekg(0, std::ios::end);
size_t len = in.tellg();
if (len == 0) return;</p>
<pre class="brush:php;toolbar:false;">std::ofstream out(output_path, std::ios::binary);
out.exceptions(std::ios::failbit | std::ios::badbit);

std::vector<char> buf(64 * 1024); // 64KB buffer
off_t pos = len - 1;

while (pos >= 0) {
    // 每次读 1 字节(保证顺序不乱),写入缓冲区,满则刷盘
    in.seekg(pos--);
    in.read(buf.data(), 1);
    out.write(buf.data(), 1);
}</char>

}

⚠️ 注意:in.seekg(pos--) 在超大文件上仍可能慢(每次 syscall)。生产环境建议改用 mmap + 指针遍历(Linux)或 CreateFileMapping(Windows),但需手动处理页面对齐和 EOF 边界。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

容易被忽略的坑:换行符、BOM、稀疏文件

Windows 下 \r\n 反转后变成 \n\r,不再是合法换行;UTF-8 BOM(\xEF\xBB\xBF)反转后变成 \xBF\xBB\xEF,目标文件无法被编辑器识别。稀疏文件(含大量零块)用上述方法会把空洞全展开成真实字节,导致输出文件暴涨。

如果业务真需要语义正确的“文本反转”(比如倒序显示日志行),应该按行读取、存入 std::vector<:string>、再 std::reverse 容器,而不是字节反转——这是两类问题,别混用同一套逻辑。

字节反转本身很简单,难的是你到底想反转什么:是磁盘上的原始字节流,还是人类可读的文本语义?选错方向,后面所有优化都是白忙。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7259

3

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

379

31

常见的编码方式
常见的编码方式

常见的编码方式有ASCII编码、Unicode编码、UTF-8编码、UTF-16编码、GBK编码等。想了解更多编码方式相关内容,可以阅读本专题下面的文章。

2023.10.24

1528

7

a和A对应的ASCII码数值
a和A对应的ASCII码数值

a的ascii码是65,a的ascii码是97;ascii码表中,一个字母的大小写数值相差32,一般知道大写字母的ascii码数值,其对应的小写字母的ascii码数值就算出来了,是大写字母的ascii码数值“+32”。想了解更多相关的内容,可阅读本专题下面的相关文章。

2024.10.24

5627

11

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3419

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2978

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1548

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2719

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3350

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习