您的位置:首页 > 编程语言 > Python开发

Python write模式导致的bug

2016-05-11 14:17 399 查看
今天遇到一个因为写文件模式不正确导致的一个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’就能避免这样的错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: