сегментирование и запись двоичного файла с использованием Python - PullRequest
0 голосов
/ 19 ноября 2011

У меня есть два двоичных входных файла, firstfile и secondfile. secondfile - это firstfile + дополнительный материал. Я хочу выделить этот дополнительный материал в отдельный файл, newfile. Это то, что я до сих пор:

import os
import struct

origbytes = os.path.getsize(firstfile)
fullbytes = os.path.getsize(secondfile)
numbytes = fullbytes-origbytes

with open(secondfile,'rb') as f:
    first = f.read(origbytes)
    rest = f.read()

Естественно, я склонен делать (что, кажется, работает):

with open(newfile,'wb') as f:
    f.write(rest)

Я не могу найти его, но подумал, что я прочитал на SO, что мне нужно сначала упаковать это, используя struct.pack перед записью в файл. Следующее дает мне ошибку:

with open(newfile,'wb') as f:
    f.write(struct.pack('%%%ds' % numbytes,rest))

-----> error: bad char in struct format

Это работает, однако:

with open(newfile,'wb') as f:
    f.write(struct.pack('c'*numbytes,*rest))

А для тех, кто работает, это дает мне правильный ответ

with open(newfile,'rb') as f:
    test = f.read()

len(test)==numbytes

-----> True

Это правильный способ записи двоичного файла? Я просто хочу убедиться, что я делаю эту часть правильно, чтобы диагностировать, если вторая часть файла повреждена как другая программа чтения, которую я передаю newfile, которая сообщает мне, или я делаю это неправильно. Спасибо.

Ответы [ 4 ]

3 голосов
/ 19 ноября 2011

Если вы знаете, что второй файл такой же, как первый файл + добавленные данные, зачем вообще читать первую часть второго файла?

with open(secondfile,'rb') as f:
    f.seek(origbytes)
    rest = f.read()

Что касается выписывания вещей,

with open(newfile,'wb') as f:
    f.write(rest)

просто отлично. Материал с struct был бы просто неактивным в любом случае. Единственное, что вы можете рассмотреть, это размер rest. Если он может быть большим, вы можете читать и записывать данные в блоках.

2 голосов
/ 19 ноября 2011

Нет смысла использовать модуль struct, который предназначен для преобразования между двоичными форматами и объектами Python. Здесь нет необходимости в преобразовании.

Строки в Python 2.x являются просто массивом байтов и могут быть прочитаны и записаны в файлы и из файлов. (В Python 3.x функция чтения возвращает объект bytes, что то же самое, если открыть файл с помощью open(filename, 'rb').)

Таким образом, вы можете просто прочитать файл в строку, а затем записать его снова:

import os

origbytes = os.path.getsize(firstfile)
fullbytes = os.path.getsize(secondfile)
numbytes = fullbytes-origbytes

with open(secondfile,'rb') as f:
    first = f.seek(origbytes)
    rest = f.read()

with open(newfile,'wb') as f:
    f.write(rest)
1 голос
/ 19 ноября 2011
  1. Вам не нужно читать origbytes, просто переместите указатель файла в правильное положение: f.seek(numbytes)
  2. Вам не нужна struct упаковка, напишите rest в newfile.
0 голосов
/ 19 ноября 2011

Это не c, в строке формата нет%. То, что вы хотите:

f.write(struct.pack('%ds' % numbytes,rest))

У меня это сработало:

>>> struct.pack('%ds' % 5,'abcde')
'abcde'

Объяснение: '%%%ds' % 15 - это '%15s', а вы хотите '%ds' % 15, что составляет '15s'

...