c++中如何进行二进制文件读写_c++ read与write函数用法
技术百科
穿越時空
发布时间:2026-01-01
浏览: 次 必须使用ios::binary标志读写二进制文件,正确检查gcount()和fail(),控制结构体填充并统一字节序,否则数据会损坏。
直接用 read() 和 write() 读写二进制文件必须用 ios::binary
不加这个标志,read() 和 write() 在 Windows 下会把 \x0A(LF)和 \x0D\x0A(CRLF)互相转换,导致二进制数据损坏。Linux/macOS 虽然影响小,但行为不一致,必须统一加。
-
std::ifstream和std::ofstream构造时传入std::ios::binary - 不能只靠
open()后再调用setf(std::ios::binary)—— 这个调用无效 - 如果同时要读写,用
std::fstream并带上ios::in | ios::out | ios::binary
read() 和 write() 的参数是 char* 和字节数,不是对象引用
它们不识别类型,只按字节搬运。想写一个 int 或结构体,必须取地址并转成 char*,且确保内存布局安全(比如没虚函数、没非 POD 成员)。
- 写一个
int x = 42:file.write(reinterpret_cast(&x), sizeof(x)) - 读回:
file.read(reinterpret_cast(&x), sizeof(x)) - 结构体可读写前提是
std::is_trivially_copyable_v为true(大多数纯数据 struct 满足) - 千万别传
std::string或std::vector本体——它们内部指针不会被序列化
务必检查 gcount() 和 fail(),不能只看 eof()
read() 可能因文件末尾、磁盘错误或权限问题提前终止,gcount() 返回**实际读取字节数**,它可能小于你请求的长度;fail() 在出错后才置位,eof( 只表示上次操作碰到了结尾,不是当前状态。
)
- 写操作同样要检查:
if (!file) { /* 写失败 */ } - 读循环典型写法:
while (file.read(buf, sizeof(buf))) { size_t n = file.gcount(); // 处理 n 字节 } if (file.fail() && !file.eof()) { // 真正出错了 } - 不要用
while (!file.eof())控制读循环——它会导致多读一次失败
跨平台二进制文件要注意字节序和结构体填充
即使你正确用了 ios::binary,在 x86(小端)和 ARM(可能大端)之间传输文件,或者不同编译器对同一 struct 的 padding 不同,都会让读出来的值错乱。
- 基础类型如
int32_t、uint16_t可减少歧义,但仍需约定字节序(推荐网络序:用htons()/htonl()写,ntohs()/ntohl()读) - struct 读写前用
#pragma pack(1)强制紧凑排列(但注意性能损失和对齐访问异常风险) - 更可靠的做法是定义明确的序列化格式(如 Protocol Buffers),而不是裸写内存
二进制 I/O 表面简单,但 ios::binary 忘加、gcount() 不查、结构体 padding 不控、字节序不处理——这四点踩中任意一个,文件就可能无声无息地损坏。
# ai
# 会把
# 用了
# 它会
# windows
# 会让
# 要注意
# mac
# win
# linux
# 循环
# 对象
# macos
# cos
# c++
# String
# if
# int
# 字节
# 指针
# stream
# 序列化
# 后才
# 排列
# 结构体
# while
# Struct
# char
# 错了
# ios
# 虚函数
# EOF
# 不加
# 只看
# padding
# 一加
# ofstream
# ifstream
# fstream
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么快速锁屏_Win11一键锁屏快捷键W
- Win11如何设置电源计划_Win11电源计划优化
- 如何使用Golang配置安全开发环境_防止敏感信息
- 如何在Golang中实现文件下载_Golang文件
- Win11文件夹预览图不显示怎么办_Win11缩略
- Python如何创建带属性的XML节点
- 如何用正则表达式精确匹配“start”到“end”
- Windows10电脑怎么查看硬盘通电时间_Win
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- Mac如何开启夜览模式_Mac护眼模式设置与定时
- PHP主流架构怎么处理表单验证_规则与自定义【技巧
- Win11怎么清理C盘虚拟内存_Win11清理虚拟
- C++中的Pimpl idiom是什么,有什么好处
- 如何在 Python 测试中动态配置 @backo
- php中self::能调用子类重写的方法吗_静态绑
- windows系统找不到无线网络怎么办_windo
- Linux如何安装Tomcat应用服务器_Linu
- 短链接怎么自定义还原php_修改解码规则适配需求【
- Windows 11无法安全删除U盘提示设备正在使
- 如何使用Golang实现容器自动化运维_Golan
- 如何在Golang中处理模块包路径变化_Golan
- 如何使用Golang包导出规则_控制函数和变量可见
- Windows10电脑怎么设置文件权限_Win10
- Mac如何查看电池健康百分比_Mac系统信息电源检
- Win11怎么开启自动HDR画质_Windows1
- Win11怎么关闭小组件_Win11禁用任务栏天气
- php删除数据怎么软删除_添加is_del字段标记
- php修改数据怎么改富文本_update更新htm
- Win11怎么关闭SmartScreen_禁用Wi
- Win10系统怎么查看网络连接状态_Windows
- Win11系统占用空间大怎么办 Win11深度瘦身
- Windows服务无法启动错误1067是什么_进程
- Python 模块的 __name__ 属性如何由
- Win10怎么设置开机密码_Windows10账户
- Win11文件扩展名怎么显示 Win11查看文件后
- Mac的Time Machine怎么用_Mac系统
- Win11怎么修改DNS服务器 Win11设置DN
- Win11怎么开启剪贴板历史记录_Windows1
- php中::能用于接口静态方法吗_接口静态方法调用
- 获取 PHP 文件最后修改时间的正确方法
- C++中引用和指针有什么区别?(代码说明)
- C++中的std::shared_from_thi
- Mac系统更新下载慢或失败怎么办_解决macOS升
- Win11怎么关闭任务栏小组件_Windows11
- php中常量能用::访问吗_类常量与作用域操作符使
- 如何使用Golang处理网络超时错误_Golang
- 如何使用Golang反射创建map对象_动态生成键
- Win10如何更改用户账户控制_Windows10
- Win11怎么关闭搜索历史_Win11清除任务栏搜
- php下载安装包怎么选_threadsafe与nt

QQ客服