使用Python从二进制文件复制会插入新字节(?)

使用Python从二进制文件复制会插入新字节(?),python,binaryfiles,Python,Binaryfiles,我试图打开一个由测量设备创建的文件,找到与元数据对应的字节,然后将所有其他内容写入一个新的二进制文件。(元数据部分不是问题:我知道标题,可以很容易地找到它们。我们不用担心这一点。) 问题是:当我打开文件并将字节写入新文件时,会添加新的字节,这会弄乱相关数据。具体来说,每次原始文件中有一个“0A”字节时,新文件的前面都有一个“0D”字节。 为了找出问题所在,我对代码进行了多次修改。以下是最新和最简单的版本,它们以三种不同的方式产生相同的结果: import os import mmap file

我试图打开一个由测量设备创建的文件,找到与元数据对应的字节,然后将所有其他内容写入一个新的二进制文件。(元数据部分不是问题:我知道标题,可以很容易地找到它们。我们不用担心这一点。)

问题是:当我打开文件并将字节写入新文件时,会添加新的字节,这会弄乱相关数据。具体来说,每次原始文件中有一个“0A”字节时,新文件的前面都有一个“0D”字节。 为了找出问题所在,我对代码进行了多次修改。以下是最新和最简单的版本,它们以三种不同的方式产生相同的结果:

import os
import mmap

file_name = raw_input('Name of the file to be edited: ')
f = open(file_name, 'rb') 

#1st try: using mmap, to make the metadata sarch easier
s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
full_data = s.read(len(s))
with open(os.path.join('.', 'edited', ('[mmap data]' + file_name + '.bin')), 'a') as data_mmap:
    data_mmap.write(full_data)

#2nd try: using bytes, in case mmap was giving me trouble

f_byte = bytes(f.read())
with open(os.path.join('.', 'edited', ('[bytes data]' + file_name + '.bin')), 'a') as data_bytes:
    data_bytes.write(f_byte)

s.close()
f.close()

#3rd try: using os.read/write(file) instead of file.read() and file.write().
from os.path import getsize

o = os.open(file_name,os.O_BINARY)  #only available on Windows
f_os = bytes(os.read(o,getsize(file_name)))
with open(os.path.join('.', 'edited', ('[os data]' + file_name + '.bin')), 'a') as data_os:
    os.write(data_os.fileno(),f_os)

os.close(o)
结果文件都是相同的(与HxD相比)。除单个新字节外,它们几乎与原始文件相同。例如,从偏移量0120开始,原始文件读取: A00A000 而新文件的内容如下: A0 0D 0A 00…然后一切都完全相同,直到原始文件中再次出现0A,其中再次出现0D字节

由于代码非常简单,我假设错误来自read函数(或者可能来自操作系统不可避免的固有行为……顺便说一句,我正在Windows上使用python 2.7) 起初我也怀疑数据格式,但在我看来,它应该是无关的。我只是在复制一切,不管价值如何

我找不到有帮助的文档,所以。。。有人知道是什么原因吗


编辑:顺便说一句,同样的脚本在Linux上工作得很好。因此,虽然这不是一个大问题,但它非常烦人。

欢迎来到线端标记的世界!在Windows下以文本模式打开文件时,任何原始
\n
(十六进制0x0a)都将写入
\r\n
(十六进制0x0d 0x0a)

幸运的是,修复起来很容易:只需以二进制模式打开文件(注意b):


不需要的
\r
将不再困扰您:-)

您将以二进制模式打开源文件,而以文本模式打开目标文件。以二进制模式打开这两个文件,Python就不会修改换行标记了。该死。我知道它必须是简单的,我不知道它会这么简单!谢谢
with open(..., 'ab') as data_...: