我正在处理一些 CSV 文件,代码如下:
reader = csv.reader(open(filepath, "rU"))
try:
for row in reader:
print 'Row read successfully!', row
except csv.Error, e:
sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
一个文件抛出这个错误:
file my.csv, line 1: line contains NULL byte
我能做什么?谷歌似乎暗示它可能是一个不正确地保存为 .csv 的 Excel 文件。有什么办法可以在 Python 中解决这个问题?
== 更新 ==
根据下面@JohnMachin 的评论,我尝试将这些行添加到我的脚本中:
print repr(open(filepath, 'rb').read(200)) # dump 1st 200 bytes of file
data = open(filepath, 'rb').read()
print data.find('\x00')
print data.count('\x00')
这是我得到的输出:
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00\x00\x00\x00\x00\x00\x00\ .... <snip>
8
13834
所以文件确实包含 NUL 字节。
最佳答案
正如@S.Lott 所说,您应该以“rb”模式打开文件,而不是“rU”模式。但是,这可能不会导致您当前的问题。据我所知,如果数据中嵌入了 \r
,使用 'rU' 模式会搞砸你,但不会引起任何其他戏剧性事件。我还注意到您有多个文件(全部以“rU”打开??)但只有一个导致问题。
如果 csv 模块说您的文件中有一个“NULL”(愚蠢的消息,应该是“NUL”)字节,那么您需要检查文件中的内容。我建议您这样做,即使使用 'rb' 可以解决问题。
repr()
是(或想成为)您的调试 friend 。它将以独立于平台的方式明确显示您所拥有的内容(这对不知道 od
是什么或做什么的帮助者很有帮助)。这样做:
print repr(open('my.csv', 'rb').read(200)) # dump 1st 200 bytes of file
并小心地将结果复制/粘贴(不要重新输入)到您的问题的编辑中(而不是评论中)。
还要注意,如果文件真的很狡猾,例如在距文件开头合理距离内没有\r 或\n 时,reader.line_num
报告的行号将是(无济于事) 1. 查找第一个 \x00
是(如果有的话)通过做
data = open('my.csv', 'rb').read()
print data.find('\x00')
并确保使用 repr 或 od 转储至少那么多字节。
data.count('\x00')
告诉你什么?如果有很多,你可能想做类似的事情
for i, c in enumerate(data):
if c == '\x00':
print i, repr(data[i-30:i]) + ' *NUL* ' + repr(data[i+1:i+31])
这样您就可以在上下文中看到 NUL 字节。
如果您可以在输出中看到 \x00
(或在 od -c
输出中看到 \0
),那么您肯定有 NUL文件中的字节,您需要执行以下操作:
fi = open('my.csv', 'rb')
data = fi.read()
fi.close()
fo = open('mynew.csv', 'wb')
fo.write(data.replace('\x00', ''))
fo.close()
顺便问一下,您是否使用文本编辑器查看过文件(包括最后几行)?它实际上看起来像其他(没有“NULL 字节”异常(exception))文件一样合理的 CSV 文件吗?
关于Python CSV 错误 : line contains NULL byte,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4166070/