Python write模式导致的bug

今天遇到一个因为写文件模式不正确导致的一个bug。因为这个bug很难被发现,所以我觉得有必要将这一个bug记录下来,往后再有使用write()函数的时候,就得小心,究竟是模式为"w",还是"wb"呢。

简单说一下问题。有一个文件有很多行,我需要读取每一行,然后将每一行的内容写到一个文本文件中,然后再通过hex_to_blob.py将文本文件的内容转为二进制文件。最后对这个二进制文件再进行处理。需求看似不复杂,一眼就能看明白。但是最后的结果证明自己给自己挖了一个大坑。

我们首先看一下这个最初的文件,文件内容如下:

17844620002270008040FF010081DF02010381F40207FBE8040E03F0081FE7E01038007C207BCFD840E07DF081FEFBE100
17844620002270008040FF010081DF02010381F40207FBE8040E03F0081FE7E01038007C207C10D840E07DF081FEFBE100
17844620002270008040FF010081DF02010381F40207FBE8040E03F0081FE7E01038007C207F80F840E07DF081FEFBE100
17844620002270008040FF010081DF02010381F40207FBE8040E03F0081FE7E01038007C207F80F840E369D081F3D3A100
17844620002270008040FF010081DF02010381F40207FBE8040E03F0081FE7E01038007C207F80F840E3EBD081F4D7A100
178446249007389C0020103FC0402077C08040E07D0081FEFA010380FC0207F9F8040E001E081FB03C10381CF8207EB9F040
文件有两万多行,这个只是最初的6行,总之这个文件的每一行都是一些十六进制数的组合。

最后的结果是两万个文件中有23个文件的结果是错误的。究竟是哪个地方导致这23个文件,也就是这两万多行中的某23行文件不对呢?这里先给出结果,错误原因就是在将每一行文件转为二进制后,将其写入文件时用的是'w',而不是‘wb’。可能你会问,为什么别的行没有问题,就这23行会有问题呢。问题就在于这23行文件有回车字符(carriage return CR)。

我们看一下出问题的一行,十六进制内容如下:

178447A4100513821C0207F408040EF010081C0FA0103F7F4020701E8040FEBF0081CA4B6103FC07C2070AAD840FF7DF0800

然后再看一下转换为二进制后的文件,这里为了直观,用了notepad++的hex-editor插件。

atgqa@atgqa-5:~/fengxi$ od -t x1 input.oamd
0000000 17 84 47 a4 10 05 13 82 1c 02 07 f4 08 04 0e f0
0000020 10 08 1c 0f a0 10 3f 7f 40 20 70 1e 80 40 fe bf
0000040 00 81 ca 4b 61 03 fc 07 c2 07 0d 0a ad 84 0f f7
0000060 df 08 00
0000062
然后再看直接用hex_to_blob.py将十六进制文件转换并直接重定向到另一个文件,而不是通过write函数将其写入。再用beyond compare软件对两个文件进行比较,以下是比较的结果。

我们可以发现,通过write()函数写进来的比通过重定向">"写进去的多了一个"0D"符合。而"0D"在十六进制中表示回车,即CR,'\r'符号。为什么会多出这么一个"0D"符号来呢?后来证明是因为通过write()函数写入时,mode为'w',因为是Windows的换行符为"\r\n",在以文本形式写入的时候,它默认将"\n"前添加了一个"\r"符号。恰恰就是这多出来的一个'r'文件导致最后的十六进制数多了一,从而导致了错误。如果在用write()函数写入时将mode设为‘wb’就能避免这样的错误。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我很高兴看到你对软件开发感兴趣,并且已经开始学习编程。根据你提供的引用内容,你目前正在实习,计划每天学习1小时左右的编程,周末学习3-4小时。这是一个很好的计划,通过持续的学习和实践,你将逐渐培养出编程的技能和兴趣。 在软件开发中,数据库是一个非常重要的组成部分。你提到了MySQL,它是一个关系型数据库管理系统,由MySQL AB开发,目前属于Oracle旗下的产品。MySQL是目前最流行的关系型数据库管理系统之一,在WEB方面,MySQL是最好的RDBMS(关系数据库管理系统)。关系数据库将数据保存在不同的表中,这样可以提高速度和灵活性。 另外,你还提供了一段Python代码,这段代码展示了如何打开和读取文件的内容,并最后关闭文件。这是一个基本的文件操作示例,你可以通过这种方式读取和处理文件中的数据。 关于你的问题,如果你想记录你的Python软件开发实习日记,你可以创建一个文本文件,然后使用Python的文件操作功能来写入你的日记内容。你可以使用类似下面的代码来实现: ```python # 打开文件,如果文件不存在则创建新文件 file = open("实习日记.txt", "a") # 写入日记内容 file.write("今天我学习了如何使用Python编写函数。\n") file.write("我解决了一个bug,并优化了代码的性能。\n") # 继续写入其他日记内容 # 关闭文件 file.close() ``` 这样,你就可以通过运行这段代码来将你的实习日记内容写入到名为"实习日记.txt"的文件中。每次运行代码,新的日记内容都会被追加到文件的末尾。 希望这些信息对你有帮助,祝你在软件开发实习中取得成功! #### 引用[.reference_title] - *1* [0基础学习python日记-第1天](https://blog.csdn.net/weixin_44705811/article/details/124206978)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Python学习日记(三十三) Mysql数据库篇 一](https://blog.csdn.net/weixin_33669473/article/details/113949960)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Python学习日记-第二十天- 文件](https://blog.csdn.net/arizia/article/details/127308155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值