2016-08-09 6 views
1

Я пытаюсь открыть файл, созданный измерительным оборудованием, найти соответствие байтов метаданным, а затем записать все остальное в новый двоичный файл. (Часть метаданных не проблема: я знаю заголовки и могу их легко найти. Давайте не будем об этом беспокоиться.)Копирование из двоичного файла с использованием Python вставляет новые байты (?)

Проблема: когда я открываю файл и записываю байты в новый файл, новые байты добавляются, что испортит соответствующие данные. В частности, каждый раз, когда в исходном файле имеется байт '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 исходный файл читается: A0 0A 00 00 , тогда как новый файл читает: A0 0D 0A 00 ... и тогда все будет точно таким же, как и до следующего вхождения 0A в исходный файл, где снова появляется 0D байт.

Поскольку код действительно прост, я предполагаю, что ошибка исходит из функции чтения (или, возможно, из-за какого-то неизбежного врожденного поведения ОС ... Я использую python 2.7 для Windows, BTW.) Я также подозревал формат данных сначала, но мне кажется, что должен быть неактуальным. Я просто копирую все, независимо от ценности.

Я не нашел документации, которая могла бы помочь, так что ... кто-нибудь знает, что вызывает это?

Редактировать: тот же скрипт отлично работает на Linux, кстати. Так что, хотя это была не большая проблема, это было очень очень неприятно.

+2

Открывает исходный файл в двоичном режиме, но файл назначения в текстовом режиме. Откройте оба файла в двоичном режиме, и Python не будет возиться с маркерами новой строки. –

ответ

4

Добро пожаловать в мир маркеров конца строки! Когда файл открыт в текстовом режиме под Windows, любой необработанный \n (hex 0x0a) будет записан как \r\n (hex 0x0d 0x0a).

К счастью, это легко исправить: просто открыть файл в двоичном режиме (обратите внимание на б):

with open(..., 'ab') as data_...: 

и нежелательный \r больше не будет беспокоить вас :-)

+0

Черт. Я знал, что это должно быть что-то простое, я не знал, что это так просто! Спасибо! – bernatel

Смежные вопросы