错误:unpack_from 需要一个缓冲区

4 投票
3 回答
6495 浏览
提问于 2025-05-10 15:04

我正在使用结构体来格式化一个固定分隔的文本文件。这里是前两行内容:

    Sat Jan  3 18:15:05 2009    62e907b15cbf27d5425399ebf6f0fb50ebb88f18    4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b +              50.00000000
    Fri Jan  9 02:54:25 2009    119b098e2e980a229e139a9ed01a469e518e6f26    0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 +              50.00000000

然后我用以下代码把它转换成csv格式:

import csv
import struct

fieldwidths = (-4, 24, -4, 40,-4,64,-1,1,25)  # negative widths represent ignored padding fields
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's')
                        for fw in fieldwidths)
fieldstruct = struct.Struct(fmtstring)
parse = fieldstruct.unpack_from

c = csv.writer(open("/home/ulrich/Desktop/disertation/sample_parsed_blch1.csv", "wb"))
with open('/home/ulrich/Desktop/disertation/sample_parsed_blch2.txt') as f:
    for line in f:
        fields = parse(line)
        c.writerow(fields)

这个过程运行得很好,成功生成了csv文件,但我还是收到了这个错误信息:

error: unpack_from requires a buffer of at least 167 bytes

相关文章:

  • 暂无相关问题
暂无标签

3 个回答

0

如果你在读取文件的时候,每一行的内容后面会有一个换行符。你需要把这个换行符去掉:

....
for line in f:
    fields = parse(line.rstrip('\r\n'))
    c.writerow(fields)
0

我最后加了一个条件,用正则表达式来只解析那些格式合适的行。

import csv
import struct
import re
pattern = re.compile("\s{4}\w{3}\s{1}.+")


fieldwidths = (-4, 24, -4, 40,-4,64,-1,1,25)  # negative widths represent ignored padding fields
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's')
                        for fw in fieldwidths)
fieldstruct = struct.Struct(fmtstring)
parse = fieldstruct.unpack_from

c = csv.writer(open("/media/ulrich/FC9A-C444/all_tx.csv", "wb"))
with open('/media/ulrich/FC9A-C444/all_tx.txt') as f:
    for line in f:
        if pattern.match(line):
            fields = parse(line)
            c.writerow(fields)
1

这种错误可能是因为文件末尾多了额外的字符。有些来自Windows的编辑器会在文本文件的末尾加上一个Ctrl-Z。这是因为当年MS/DOS想要和CP/M保持兼容,留下的一个痕迹。

你可以通过跳过较短的行来轻松解决这个问题:

for line in f:
    if len(line) >= minsize # 100
        fields = parse(line)
        c.writerow(fields)

撰写回答