Python CSV 错误: line 包含 NULL 字节

我正在处理一些 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

我能做什么?Google 似乎暗示它可能是一个 Excel 文件,被保存为。不正确的 CSV。有没有什么方法可以在 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 字节。

172649 次浏览

你为什么要这么做?

 reader = csv.reader(open(filepath, "rU"))

医生说得很清楚,你必须这么做:

with open(filepath, "rb") as src:
reader= csv.reader( src )

模式必须是“ rb”才能读取。

Http://docs.python.org/library/csv.html#csv.reader

如果 csvfile 是一个 file 对象,那么必须在平台上使用‘ b’标志打开它,这样做会有所不同。

As @S.Lott says, you should be opening your files in 'rb' mode, not 'rU' mode. However that may NOT be causing your current problem. As far as I know, using 'rU' mode would mess you up if there are embedded \r in the data, but not cause any other dramas. I also note that you have several files (all opened with 'rU' ??) but only one causing a problem.

If the csv module says that you have a "NULL" (silly message, should be "NUL") byte in your file, then you need to check out what is in your file. I would suggest that you do this even if using 'rb' makes the problem go away.

repr()是(或希望是)您的调试伙伴。它将以独立于平台的方式明确地显示您所获得的内容(这对于不知道 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')

and make sure that you dump at least that many bytes with repr or 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()

By the way, have you looked at the file (including the last few lines) with a text editor? Does it actually look like a reasonable CSV file like the other (no "NULL byte" exception) files?

显然是 XLS 文件,不是 http://www.garykessler.net/library/file_sigs.html确认的 CSV 文件

我也碰到了这个问题。通过使用 Python csv模块,我试图读取在 MS Excel 中创建的 XLS 文件,并且遇到了 NULL byte错误。我环顾四周,找到了用于从 MSExcel 电子表格文件中读取和格式化数据的 第三集 Python 模块。使用 xlrd模块,我不仅能够正确地读取文件,而且还能以以前不能的方式访问文件的许多不同部分。

I thought it might help you.

我得到了同样的错误。保存的文件在 UTF-8和它的工作。

Converting the encoding of the source file from UTF-16 to UTF-8 solve my problem.

如何在 Python 中将文件转换为 utf-8?

import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open(sourceFileName, "r", "utf-16") as sourceFile:
with codecs.open(targetFileName, "w", "utf-8") as targetFile:
while True:
contents = sourceFile.read(BLOCKSIZE)
if not contents:
break
targetFile.write(contents)

我没有使用 csv reader,而是为 string 使用 read file 和 split 函数:

lines = open(input_file,'rb')


for line_all in lines:


line=line_all.replace('\x00', '').split(";")

当我使用 OpenOfficeCalc 创建一个 CSV 文件时,就发生了这种情况。当我在文本编辑器中创建 CSV 文件时,即使我后来用 Calc 编辑它,也没有发生这种情况。

我通过在文本编辑器中将 Calc 创建的文件中的数据复制粘贴到新的编辑器创建的文件中来解决这个问题。

我遇到了同样的问题,打开了一个从 webservice 生成的 CSV,它在空头中插入了 NULL 字节。我做了以下工作来清理文件:

with codecs.open ('my.csv', 'rb', 'utf-8') as myfile:
data = myfile.read()
# clean file first if dirty
if data.count( '\x00' ):
print 'Cleaning...'
with codecs.open('my.csv.tmp', 'w', 'utf-8') as of:
for line in data:
of.write(line.replace('\x00', ''))


shutil.move( 'my.csv.tmp', 'my.csv' )


with codecs.open ('my.csv', 'rb', 'utf-8') as myfile:
myreader = csv.reader(myfile, delimiter=',')
# Continue with your business logic here...

免责声明: 请注意,这会覆盖原始数据。确保你有备份。我警告过你了!

对于那些“ rU”文件模式的讨厌者: 我刚刚尝试用“ rb”文件模式从 Mac 上的 Windows 机器上打开一个 CSV 文件,我从 CSV 模块得到了这个错误:

Error: new-line character seen in unquoted field - do you need to
open the file in universal-newline mode?

在‘ rU’模式下打开文件效果很好。我喜欢通用换行模式——它为我省去了很多麻烦。

把它读成 UTF-16也是我的问题。

Here's my code that ended up working:

f=codecs.open(location,"rb","utf-16")
csvread=csv.reader(f,delimiter='\t')
csvread.next()
for row in csvread:
print row

位置是您的 csv 文件的目录。

我在使用 scrapy 并获取压缩的 csvfile 时遇到了这个问题,当时没有正确的中间件来解压缩响应主体,然后将其交给 csvreader。因此,该文件并不是一个真正的 csv 文件,因此抛出了 line contains NULL byte错误。

如果你想假装它们不存在,你可以直接内联一个生成器来过滤掉空值。当然,这是假设空字节不是编码的一部分,而是某种错误的工件或 bug。

with open(filepath, "rb") as f:
reader = csv.reader( (line.replace('\0','') for line in f) )


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))
data_initial = open("staff.csv", "rb")
data = csv.reader((line.replace('\0','') for line in data_initial), delimiter=",")

这对我有用。

一种情况是-如果 CSV 文件包含空行,这个错误可能会显示出来。在继续写入或读取之前,必须检查行。

for row in csvreader:
if (row):
do something

我通过在代码中添加这个检查来解决我的问题。

你试过用 gzip.open 吗?

with gzip.open('my.csv', 'rb') as data_file:

我试图打开一个文件,已经被压缩,但有扩展名’。而不是“ csv.gz”。这个错误一直出现,直到我使用 gzip.open

我打开原来的 csv 文件并通过 Excel 的“另存为”保存为 .csv文件,NULL 字节消失了。

我认为我收到的文件的原始编码是双字节 Unicode (每隔一个字符有一个空字符) ,所以通过 Excel 保存它修复了编码。