使用不同格式字符串的Python struct.struct.unpack_时遇到困难
第一次海报,长期潜伏者。我们已经到处寻找答案,但它已经到了那个阶段 我在执行John Machin对过去问题的回答时遇到了一些困难: 在一个非常高的层次上,我使用这段代码分割固定格式的文本文件,并将它们导入PostgreSQL数据库。我已经成功地使用此代码实现了一个文本文件的解决方案,但是我现在尝试扩展我的程序以处理不同固定格式的不同文本文件,并且不断遇到相同的错误:使用不同格式字符串的Python struct.struct.unpack_时遇到困难,python,c,parsing,struct,buffer,Python,C,Parsing,Struct,Buffer,第一次海报,长期潜伏者。我们已经到处寻找答案,但它已经到了那个阶段 我在执行John Machin对过去问题的回答时遇到了一些困难: 在一个非常高的层次上,我使用这段代码分割固定格式的文本文件,并将它们导入PostgreSQL数据库。我已经成功地使用此代码实现了一个文本文件的解决方案,但是我现在尝试扩展我的程序以处理不同固定格式的不同文本文件,并且不断遇到相同的错误: struct.error: unpack_from requires a buffer of at least [x] byt
struct.error: unpack_from requires a buffer of at least [x] bytes
当然,我得到的x值不同,这取决于我输入到函数的格式字符串——我的问题是,它只适用于一种格式,而不适用于任何其他格式。我唯一要更改的是用于计算格式字符串的变量,以及脚本中与格式相关的变量名
例如,这很好:
cnv_text = lambda s: str(s.strip())
cnv_int = lambda s: int(s) if s.isspace() is False else s.strip()
cnv_date_ymd = lambda s: datetime.datetime.strptime(s, '%Y%m%d') if s.isspace() is False else s.strip() # YYYY-MM-DD
unpack_len = 0
unpack_fmt = ""
splitData = []
conn = psycopg2.connect("[connection info]")
cur = conn.cursor()
Table1specs = [
('A', 6, 14, cnv_text),
('B', 20, 255, cnv_text),
('C', 275, 1, cnv_text),
('D', 276, 1, cnv_text),
('E', 277, 1, cnv_text),
('F', 278, 1, cnv_text),
('G', 279, 1, cnv_text),
('H', 280, 1, cnv_text),
('I', 281, 8, cnv_date_ymd),
('J', 289, 8, cnv_date_ymd),
('K', 297, 8, cnv_date_ymd),
('L', 305, 8, cnv_date_ymd),
('M', 313, 8, cnv_date_ymd),
('N', 321, 1, cnv_text),
('O', 335, 2, cnv_text),
('P', 337, 2, cnv_int),
('Q', 339, 5, cnv_int),
('R', 344, 255, cnv_text),
('S', 599, 1, cnv_int),
('T', 600, 1, cnv_int),
('U', 601, 5, cnv_int),
('V', 606, 10, cnv_text)
]
#for each column in the spec variable...
for column in Table1specs:
start = column[1] - 1
end = start + column[2]
if start > unpack_len:
unpack_fmt += str(start - unpack_len) + "x"
unpack_fmt += str(end - start) + "s"
unpack_len = end
field_indices = range(len(Table1specs))
print unpack_len, unpack_fmt
#set unpacker
unpacker = struct.Struct(unpack_fmt).unpack_from
class Record(object):
pass
filename = "Table1Data.txt"
f = open(filename, 'r')
for line in f:
raw_fields = unpacker(line)
r = Record()
for x in field_indices:
setattr(r, Table1specs[x][0], Table1specs[x][3](raw_fields[x]))
splitData.append(r.__dict__)
所有数据都附加到splitData中,然后我在一个循环中遍历它,并将其转换为SQL语句,以便通过psycopg2输入数据库。当我将规范更改为其他内容时(其他变量也反映了这一点),我会收到错误。它从“原始字段=解包(行)”行抛出
我已经用尽了所有的资源,现在无所适从。。。欢迎任何想法或想法
(是否与我从中导入的文本文件有关?)
致以最诚挚的问候。已经解决了这个问题:问题是由我正在解析的文本文件引起的。这些行不够长,因此我编写了一个函数,将空格写入每行的末尾,以使它们具有正确的长度:
def checkLineLength(checkFile, minLength):
print ('Checking length of lines in file '+ checkFile+', where minimum line length is '+str(minLength))
counter = 0
fixedFile = 'fixed'+checkFile
src = open(checkFile, 'r')
dest = open(fixedFile, 'w')
lines = src.readlines()
for line in lines:
if len(line) < minLength:
x = (line.rstrip('\r\n') + (" "*(minLength-(len(line)-1))+'\r\n'))
dest.write(x)
counter += 1
else:
dest.write(line)
if counter > 0:
os.remove(checkFile)
os.rename(fixedFile, checkFile)
print (str(counter) + " lines fixed in "+ checkFile)
else:
print('Line length in '+checkFile+' is fine.' )
os.remove(fixedFile)
def checkLineLength(checkFile,minLength):
打印('检查文件'+checkFile+'中的行长度,其中最小行长度为'+str(minLength))
计数器=0
fixedFile='fixed'+检查文件
src=open(检查文件'r')
dest=打开(固定文件“w”)
lines=src.readlines()
对于行中的行:
如果len(line)0:
删除操作系统(检查文件)
重命名(修复文件、检查文件)
打印(str(计数器)+固定在“+检查文件中的”行)
其他:
打印(“+checkFile+”中的行长度很好。”)
删除操作系统(修复文件)
您能给我们一些最小的工作示例代码来重现此错误吗?@alKid添加在代码示例中-类似于链接问题答案中的代码,这就是我最初没有包含的原因:)。@user3446927-您的示例标记为“这工作正常”。请提供一个失败的代码示例。@Rob,现在已解决此问题。问题是我正在解析的文本文件-行不够长,所以我编写了一个函数,将空格写入每行的末尾,以使它们具有正确的长度。。。到目前为止似乎还可以。太好了。请删除此问题,这样其他人就不会在上面花费不必要的时间。