C/C++/Python等 使用二进制模式打开文件与不使用二进制模式的区别

本文探讨了使用C++中的ifstream读取ZIP文件时遇到的问题,即读取过程中在达到特定字节后停止。文章分析了原因,并指出这与字符模式下对控制字符的处理有关。
概述:
今天尝试使用c++中的ifstream来读取一个zip文件,结果发现每次都是读取了451个字节就结束了(测试用的zip文件4M多)。

--------------------------------------------------
author: cs_cjl
website:  http://blog.youkuaiyun.com/cs_cjl
--------------------------------------------------

测试代码:
#include <iostream>
#include <fstream>

using namespace std;

int main (int argc, char *argv[])
{
     ifstream fs(L"d:/tic.zip", std::ios::binary);
     if (fs.is_open ()) {
          cout << "file is open" << endl;
     }

     if (fs.good ()) {
          cout << "filestream is good" << endl;
     }

     char buf[200];
     size_t total_size(0);
     while (true) {
          fs.read(buf, 200);
          total_size += fs.gcount ();
          if (!fs) {
               cout << "read " << fs.gcount () << endl;
               cout << "fs.good () : " << fs.good () << endl;
               cout << "fs.eof () : " << fs.eof () <<endl;
               cout << "fs.fail () : " << fs.fail () << endl;
               break;
          }
     }

     cout << "read total size: " << total_size << endl;
     return 0;
}

通过16进制编辑器查看zip文件,发现第252个字节为0x1a,通过查看
发现它对应Ctrl+Z,由于历史原因,在字符模式下
当遇到这个字符时,读取会结束

结论:
一直以为 二进制模式 和 字符模式 的区别只是对换行符\r \n的处理的不同
通过这次测试发现除了对换行符的处理不同外,字符模式还会对一些控制字符进行处理

参考:

<think>首先,用户的问题是:“我想了解以二进制模式(rb)打开文件的相关信息 请问以二进制模式(rb)打开文件的方法相关知识”。用户提供了几个引用,我需要参考这些引用,但也要基于我的知识来回答。 回顾系统级指令: - 所有行内数学表达式使用$...$格式(但这里可能涉及数学,所以可能需要)。 - 独立公式使用$$...$$并单独成段(同样,可能适用)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 用户提供的引用: - 引用[1]:提到二进制文件如.jpg、.mp3、.exe必须使用二进制模式打开,以避免转换。 - 引用[2]:解释了Python中rb模式是只读二进制模式。 - 引用[3]:展示了以wb模式写入二进制文件打开时显示二进制符号,需要特定方式查看。 - 引用[4]:讨论了在C/C++使用时可能需要删除FF FE字节。 用户请求的是关于rb模式的信息:以二进制模式(rb)打开文件的方法相关知识。 我的回答应该结构清晰,逐步解决问题,保证真实可靠。回答内容包括: 1. **方法**:如何使用Python的open函数以rb模式打开文件。 2. **相关知识**: - 什么是二进制模式? - 为什么需要二进制模式? - 文本模式的对比。 - 常见错误注意事项。 - 示例代码。 然后,生成相关问题。 结构回答: - 先介绍二进制模式的概念。 - 解释rb模式的具体用法。 - 提供示例代码。 - 讨论相关知识点。 - 添加引用标识。 - 生成相关问题。 确保使用中文。 大纲: 1. **简介**:解释二进制模式rb模式的含义。 2. **方法**:描述如何在Python使用open函数以rb模式打开文件。 3. **示例代码**:展示读取二进制文件的代码。 4. **相关知识**: - 为什么使用二进制模式? - 二进制模式文本模式区别。 - 常见文件类型。 - 注意事项(如引用中提到的一些点)。 5. **相关问题**:生成2-3个相关的问题。 引用处理:在回答中,当引用用户提供的引用时,自然地添加[^1]、[^2]等。例如: - 当提到二进制文件必须使用二进制模式时,引用[^1]。 - 当解释rb模式时,引用[^2]。 - 当讨论二进制写入查看时,引用[^3]。 - 当提到字节顺序标记时,引用[^4]。 最终,生成相关问题。 </think>### 以二进制模式(rb)打开文件的方法相关知识 在Python编程中,文件操作是基本技能之一。二进制模式(例如 `'rb'`)用于打开文本文件(如图片、音频、可执行文件),确保数据以原始字节形式读取,避免字符编码转换导致的数据损坏。下面我将系统地介绍相关方法知识,帮助您逐步掌握这一概念。 #### 1. **二进制模式(rb)的基本概念** - **什么是二进制模式?** 二进制模式(`'r'` 表示只读,`'b'` 表示二进制)在Python中用于操作二进制文件。这种模式会对文件内容进行任何转换(如编码或解码),直接以字节序列形式处理数据。例如,`.jpg`、`.mp3` 或 `.exe` 文件必须使用二进制模式打开,否则可能导致数据错误或文件损坏[^1]。 - **为什么需要使用二进制模式?** - 文本模式(如 `'r'`)会自动处理字符编码(如 UTF-8),适用于文本文件(如 `.txt`)。但对于二进制文件,任何字符转换都会破坏原始数据(例如,图像文件中的字节可能被误解释为特殊字符)。 - 二进制模式确保数据的完整性,适合处理多媒体、压缩文件或跨平台数据交换[^1][^2]。 #### 2. **以二进制模式(rb)打开文件的方法** Python的 `open()` 函数用于打开文件模式参数指定为 `'rb'` 即可实现只读二进制模式。以下是详细步骤: - **语法**: ```python file_object = open(file_path, 'rb') ``` - `file_path`:文件路径(可以是相对或绝对路径)。 - `'rb'`:模式字符串,`'r'` 表示只读,`'b'` 表示二进制。 - **关键参数**: - **只读(r)**:文件只能被读取,能写入。 - **二进制(b)**:文件内容以字节(bytes)对象读取,而字符串。 - **返回值**:函数返回一个文件对象,支持二进制读取操作(如 `.read()`)。 - **注意事项**: - 关闭文件使用后必须调用 `.close()` 方法释放资源,或使用 `with` 语句自动管理。 - 错误处理:如果文件存在或路径错误,会触发 `FileNotFoundError` 异常。 #### 3. **示例代码** 下面是一个完整的Python示例,演示如何以 `'rb'` 模式打开文件并读取数据: ```python # 以二进制只读模式打开文件 file_path = 'example.jpg' # 假设这是一个图片文件 with open(file_path, 'rb') as file: # 读取整个文件内容为字节序列 data = file.read() print(f"读取的字节数: {len(data)}") # 示例输出:读取的字节数: 1024(取决于文件大小) # 注意:二进制数据在控制台显示为b'...'格式,易直接阅读[^3] ``` - **解释**: - 使用 `with open(...) as file` 确保文件在操作后自动关闭。 - `file.read()` 返回一个 `bytes` 对象,包含文件的原始字节。 - 二进制数据通常在IDE或文本编辑器中显示为十六进制或乱码(因为它是可读文本),需要特定工具(如Hex编辑器)查看[^3]。 #### 4. **相关知识扩展** - **rb 模式文本模式区别**: - **文本模式(如 `'r'`)**:自动处理编码,读取内容为字符串。适合 `.txt`、`.csv` 等文本文件。但打开二进制文件时,可能因编码转换损坏数据(例如,某些字节被解释为换行符)。 - **二进制模式(如 `'rb'`)**:保留原始字节,无任何转换。适用于所有文本文件,确保数据原样读取[^1][^2]。 - 对比表: | 特性 | 文本模式('r') | 二进制模式('rb') | |--------------------|------------------|---------------------| | 内容类型 | 字符串(str) | 字节序列(bytes) | | 编码处理 | 自动应用(如UTF-8)| 无转换 | | 适用文件 | 文本文件(.txt) | 二进制文件(.jpg, .mp3) | | 常见错误 | 编码错误导致乱码 | 数据完整性高 | - **为什么二进制文件必须使用二进制模式?** 二进制文件(如图像、音频)包含文本数据(如像素值、音频采样)。文本模式会尝试将其解码为字符,可能引发错误(如 UnicodeDecodeError)或改变文件结构[^1][^3]。 - **常见应用场景**: - 多媒体处理:读取图像(`.jpg`)、音频(`.mp3`)或视频文件。 - 数据传输:网络协议或API通信中处理原始字节流。 - 跨语言兼容:如在C/C++程序中写入的数据,Python二进制读取可能需处理字节顺序标记(如删除 FF FE 字节)[^4]。 - **注意事项**: - **数据查看**:二进制数据在Python中显示为类似 `b'\xff\xd8...'` 的格式。要查看内容,需使用专业工具(如Python的 `hex()` 函数或IDE的二进制查看器)[^3]。 - **写入二进制文件**:类似地,写入使用 `'wb'` 模式二进制只写)。但 `'rb'` 模式只支持读取操作,写入会出错。 - **性能优势**:二进制模式通常更高效,因为它跳过了编码/解码步骤。 - **错误处理**:在尝试读取时,如果文件较大,应使用 `.read(size)` 分批读取以避免内存溢出。 #### 5. **总结** 以二进制模式(`'rb'`)打开文件是处理文本数据的标准做法,确保数据以原始字节形式读取。这在文件处理、多媒体应用跨平台开发中至关重要。始终记住使用 `with` 语句来管理文件资源,并避免在二进制文件使用文本模式[^1][^2][^3]。如果您遇到二进制数据查看问题,建议使用Hex编辑器或Python内置工具进行分析。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值