0

0

C++怎么实现文件断点续传_C++二进制流读写操作【指南】

冰火之心

冰火之心

发布时间:2026-03-11 15:34:03

|

475人浏览过

|

来源于php中文网

原创

断点续传本质是记录并恢复文件偏移量,需用std::streamoff管理偏移、二进制模式打开文件、seekg()/seekp()跳转、clear()清理流状态、原子化持久化断点信息。

c++怎么实现文件断点续传_c++二进制流读写操作【指南】

断点续传本质是“记录并恢复文件偏移量”

断点续传在 C++ 里不是某个函数直接支持的功能,而是靠自己管理已写入的字节数(即偏移量),再用 std::ifstreamstd::ofstreamseekg()/seekp() 跳到对应位置继续读写。关键不在“怎么传”,而在“怎么记”和“怎么跳”。

常见错误现象:seekg() 后读不到数据、文件末尾多出乱码、续传后校验失败——八成是偏移量没对齐或流状态没清。

  • 必须用二进制模式打开:std::ios::binary,否则 Windows 下换行符会被转换,偏移错乱
  • 记录偏移量不能只存整数,得用 std::streamoff 类型(而非 intsize_t),它能跨平台表示大文件偏移
  • 每次 seekg()seekp() 后,检查 fail():比如 if (file.fail()) { /* 处理错误 */ }
  • 续传前先 clear() 流状态,否则上次失败会卡住后续所有操作

seekp() 从指定位置继续写入

服务端或客户端保存了上次写到第 N 字节,下次就得让 std::ofstream 从那里开始追加,而不是覆盖开头。注意:C++ 没有“append from offset”这种模式,std::ios::app 只能追加到末尾,必须用 seekp(N) + std::ios::out

使用场景:下载中断后重新连接,本地文件已存在且部分完成,需接着写。

立即学习C++免费学习笔记(深入)”;

IBM Watson
IBM Watson

IBM Watson文字转语音

下载
  • 打开文件时用 std::ios::out | std::ios::binary,不要加 std::ios::trunc
  • 调用 file.seekp(N) 后,立刻 file.clear(),再检查 file.good()
  • 如果 N 大于当前文件长度,写入会在中间留空(表现为 \0 字节),这是合法行为,但需确保接收方能处理稀疏区域
  • 写完记得 file.flush(),尤其在非阻塞传输中,避免缓冲区未落盘就认为写成功

读取时用 seekg() 跳过已接收部分

上传端要从第 N 字节开始读原文件,避免重复发送。这里容易忽略的是:读取偏移必须和写入偏移单位一致(都是字节),且不能跨块对齐——除非协议明确要求分块哈希,否则按字节续最稳妥。

性能影响:小文件无所谓;大文件频繁 seekg() 不影响吞吐,但会增加系统调用开销;若配合内存映射(mmap)可避免,但跨平台性下降。

  • std::ifstream file(path, std::ios::binary) 打开,别用 std::ios::ate,它会把指针直接移到末尾
  • file.seekg(N) 后,用 file.read(buf, size),别依赖 gcount() 前先检查 file.good()
  • 读到 EOF 时 gcount() 可能小于请求长度,需主动判断 file.eof()file.fail() 区分原因
  • Windows 下若文件被其他进程以独占方式打开,seekg() 会失败,错误码可能是 ERROR_SHARING_VIOLATION

偏移量持久化与校验不能只靠文件名

断点信息(如已传字节数、MD5 分段值)如果只存在内存里,崩溃就全丢;如果硬编码进文件名(比如 file.part.123456789),遇到重命名或清理脚本就失效。必须单独存,且带校验。

容易踩的坑:多个线程/进程同时更新同一断点文件,导致偏移量写乱;或者用文本格式存数字但没处理换行符,读出来多一个 \r

  • 推荐用小 JSON 或纯二进制文件存:struct { std::streamoff offset; uint64_t timestamp; char md5[16]; }
  • 写断点文件时,先写到临时路径(如 info.tmp),fsync() 后再 rename() 覆盖,保证原子性
  • 每次读断点前,用 stat() 检查文件大小是否匹配预期结构体长度,防损坏
  • 别把断点信息和下载文件放同一目录又用相似名,同步工具(如 rsync、OneDrive)可能误同步未完成状态

偏移量对齐、流状态清理、断点存储原子性——这三点漏掉任一,续传就会变成“看似在续,实则重头来”。特别是多线程环境下,seekp() 和写入之间没有锁保护的话,两个线程一前一后跳位置,数据就彻底错位了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

454

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

334

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

string转int
string转int

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

1010

2023.08.02

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号