如何在使用Python枚举文件时忽略二进制数据头(或仅读取序列化数据)?
问题描述:
我有一个文件,有一些二进制数据的标题(我想这就是它),然后,有文本行。我刚刚开始使用它,但我注意到如果我使用Python“枚举”功能,它不会出现读取我想要它读取的行(我正在使用Python 2.7.8 )。它没有返回我感兴趣的代码行。在我的文本编辑器中,我可以看到我想要的数据,但结果表明可能是“序列化数据”?文件末尾有更多相同的二进制文件。如何在使用Python枚举文件时忽略二进制数据头(或仅读取序列化数据)?
从数据文件中取样(我希望跳过前8行): 我想从以“curve”开头的行开始。
ÿÿÿÿ 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
SPaperSizeSPaperBounds
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')
>>>
答
我想通了,既然文件是二进制格式的,我需要在开放的这种方式来读它('myfile','rb')而不是open('myfile','r'),我从this question得到了很多帮助。
重新写看起来像这样...
#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
答
注意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
是 - 我是错解释启动参数。但即使我不包含启动参数,它也会返回相同的数据(只是没有计数)。它只返回5行,但文本编辑器显示54行。 – jbchurchill