Как я могу игнорировать заголовки двоичных данных (или просто читать сериализованные данные) при перечислении файла с помощью Python?

У меня есть файл с несколькими заголовками двоичных данных (я полагаю, что это так), и после этого есть строки текста. Я только начинаю с ним работать, но заметил, что если я использую функцию «перечисления» Python, она не появляется для чтения строк, которые я хочу читать (я использую Python 2.7.8). Он не возвращает строки, которые меня интересуют. В моем текстовом редакторе я вижу нужные мне данные, но результат указывает, может быть, это «сериализованные данные»? В конце файла есть еще один и тот же двоичный файл.

Пример из файла данных (надеюсь пропустить первые 8 строк): я хочу начать со строки, начинающейся со слова "кривая".

    ÿÿÿÿ          ENetDeedPlotter, Version=5.6.1.0, Culture=neutral, PublicKeyToken=null   QSystem.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a   Net_Deed_Plotter.SerializeData!   LinesOfDataNumberOfTractsSeditortextSedLineStract
SNoteArraySNorthArrow
Slandscape
SPaperSizeSPaperBounds
SPrinterScaleSPrinterScaleStrSAllTractsMouseOffsetNSAllTractsMouseOffsetESAllTractsNOffsetSAllTractsEOffsetSImageScroll_YSImageScroll_XSImage_YSImage_XSImageFilePath
SUpDateMapSttcSttStbSboSnb
STitleText  SDateText   SPOBLines
SLabelCornersSNAmountTract0HasBeenMovedSEAmountTract0HasBeenMoved                      Net_Deed_Plotter.LineData[]   Net_Deed_Plotter.TractData[]   System.Collections.ArrayList+Net_Deed_Plotter.PaperForm+NorthArrowStruct   !System.Drawing.Printing.PaperSize   System.Drawing.Rectangle      '         Ân40.4635w 191.02
curve right radius 953.50 arc 361.84 chord n60.5705e 359.07
s56.3005e 3.81
s19.4515w 170.63
s13.4145w 60.67
s51.0250w 155.35
n40.4635w 191.02
curve left radius 615.16 arc 202.85 chord s45.19w 201.94

Пример сценария

# INPUTS TO BE UPDATED
inputNDP = r"N:\Parcels\Parcels2012\57-11-115.ndp"
outputTXT = r"N:\Parcels\Parcels2012\57-11-115.txt"
# END OF INPUTS TO BE UPDATED
fileNDP = open(inputNDP, 'r')
for line in enumerate(9, fileNDP):
    print line

Результат

(9, '\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x0c\x02\x00\x00\x00ENetDeedPlotter, Version=5.6.1.0, Culture=neutral, PublicKeyToken=null\x0c\x03\x00\x00\x00QSystem.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\x05\x01\x00\x00\x00\x1eNet_Deed_Plotter.SerializeData!\x00\x00\x00\x0bLinesOfData\x0eNumberOfTracts\x0bSeditortext\x07SedLine\x06Stract\n')
(10, 'SNoteArray\x0bSNorthArrow\n')
(11, 'Slandscape\n')
(12, 'SPaperSize\x0cSPaperBounds\rSPrinterScale\x10SPrinterScaleStr\x16SAllTractsMouseOffsetN\x16SAllTractsMouseOffsetE\x11SAllTractsNOffset\x11SAllTractsEOffset\x0eSImageScroll_Y\x0eSImageScroll_X\x08SImage_Y\x08SImage_X\x0eSImageFilePath\n')
(13, 'SUpDateMap\x04Sttc\x03Stt\x03Stb\x03Sbo\x03Snb\n')
(14, 'STitleText\tSDateText\tSPOBLines\rSLabelCorners')
>>> 

person jbchurchill    schedule 13.05.2016    source источник


Ответы (2)


Имейте в виду, что enumerate принимает параметр start, который устанавливает только начальное значение числа. Это не заставляет его пропускать какое-либо содержимое.

Если вы хотите пропустить строки, вам нужно отфильтровать перечисление:

x=xrange(20)
>>> for num,text in (tpl for tpl in enumerate(x) if tpl[0] >8):
...   print num,text
...
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
person aghast    schedule 13.05.2016
comment
да - я неправильно интерпретировал начальный параметр. но даже если я не включаю начальный параметр, он возвращает те же данные (только без подсчета). Он возвращает только 5 строк, но текстовый редактор показывает 54 строки. - person jbchurchill; 13.05.2016

Я понял, что, поскольку файл был в двоичном формате, мне нужно было прочитать его таким образом с помощью open('myfile', 'rb'), а не с помощью open('myfile', 'r'), и я получил много помощи из этого вопроса.

Переписка выглядит так...

#ToDO write output file
# INPUTS TO BE UPDATED
inputNDP = r"N:\Parcels\Parcels2012\57-11-115.ndp"
# END OF INPUTS TO BE UPDATED
fileNDP = open(inputNDP, 'rb')
def strip_nonascii(b):
    return b.decode('ascii', errors='ignore')

n = 0
for line in fileNDP:
    if n > 5:
        if '|' in line:
            break
        print(strip_nonascii(line)).strip('\n') # + str(n)
    n += 1
person jbchurchill    schedule 13.05.2016