【问题标题】:How can I ignore binary data headers (or just read the serialized data) when enumerating a file with Python?使用 Python 枚举文件时,如何忽略二进制数据头(或仅读取序列化数据)?
【发布时间】:2016-05-13 18:25:52
【问题描述】:

我有一个文件,其中包含许多二进制数据的标题(我想就是这样),然后是文本行。我刚开始使用它,但我注意到如果我使用 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
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')
>>> 

【问题讨论】:

    标签: python python-2.7 binaryfiles enumerate


    【解决方案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
    

    【讨论】:

    • 是的 - 我误解了 start 参数。但即使我不包含开始参数,它也会返回相同的数据(只是没有计数)。它只返回 5 行,但文本编辑器显示 54 行。
    【解决方案2】:

    我发现由于该文件是二进制格式,因此我需要使用 open('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
    

    【讨论】:

      猜你喜欢
      • 2022-08-15
      • 1970-01-01
      • 2019-09-25
      • 2013-03-23
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      相关资源
      最近更新 更多