我正在处理一些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
我该怎么办?谷歌似乎暗示它可能是一个Excel文件被不正当地保存为.csv。有什么方法可以解决这个问题吗?
== UPDATE ==
按照下面@ 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字节。
答案 0 :(得分:96)
正如@ S.Lott所说,你应该在'rb'模式下打开文件,而不是'rU'模式。但是,这可能不会导致您当前的问题。据我所知,如果数据中嵌入\r
,使用'rU'模式会让你感到困惑,但不会导致其他任何戏剧。我还注意到你有几个文件(所有文件都打开'rU'??)但只有一个文件导致问题。
如果csv模块说你的文件中有一个“NULL”(愚蠢的消息,应该是“NUL”)字节,那么你需要检查文件中的内容。我建议你这样做,即使使用'rb'也会让问题消失。
repr()
是(或想成为)您的调试朋友。它将以平台独立的方式明确地显示您所拥有的内容(这对于不知道od
是什么或不知道的帮助者是有帮助的)。这样做:
print repr(open('my.csv', 'rb').read(200)) # dump 1st 200 bytes of file
并小心地将结果复制/粘贴(不要重新输入)到您的问题的编辑中(而不是注释)。
另请注意,如果文件非常狡猾,例如:在距文件开头合理距离内没有\ r或\ n,reader.line_num
报告的行号将是(无用的)1。通过执行<查找第一个\x00
的位置(如果有) / p>
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
(或\0
输出中的od -c
),那么你肯定在文件中有NUL字节,你需要做这样的事情:
fi = open('my.csv', 'rb')
data = fi.read()
fi.close()
fo = open('mynew.csv', 'wb')
fo.write(data.replace('\x00', ''))
fo.close()
顺便问一下,你是否用文本编辑器查看了文件(包括最后几行)?它实际上看起来像另一个合理的CSV文件(没有“NULL字节”异常)文件吗?
答案 1 :(得分:17)
将它读作UTF-16也是我的问题。
这是我的代码最终工作:
f=codecs.open(location,"rb","utf-16")
csvread=csv.reader(f,delimiter='\t')
csvread.next()
for row in csvread:
print row
其中location是csv文件的目录。
答案 2 :(得分:16)
data_initial = open("staff.csv", "rb")
data = csv.reader((line.replace('\0','') for line in data_initial), delimiter=",")
这适合我。
答案 3 :(得分:12)
我也遇到了这个问题。使用Python csv
模块,我试图读取在MS Excel中创建的XLS文件并遇到您遇到的NULL byte
错误。我环顾四周,找到了xlrd Python模块,用于从MS Excel电子表格文件中读取和格式化数据。使用xlrd
模块,我不仅能够正确读取文件,而且还可以以前所未有的方式访问文件的许多不同部分。
我认为这对你有所帮助。
答案 4 :(得分:10)
将源文件的编码从UTF-16转换为UTF-8解决了我的问题。
How to convert a file to utf-8 in Python?
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)
答案 5 :(得分:7)
如果您想假装它们不存在,您可以内联生成器来过滤掉空值。当然这是假设空字节实际上不是编码的一部分,实际上是某种错误的工件或错误。
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))
答案 6 :(得分:2)
你为什么这样做?
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是一个文件对象,则必须在平台上打开“b”标志,这会产生影响。
答案 7 :(得分:2)
显然它是一个XLS文件而不是CSV文件http://www.garykessler.net/library/file_sigs.html确认
答案 8 :(得分:2)
我使用read文件和split函数代替csv reader而不是字符串:
lines = open(input_file,'rb')
for line_all in lines:
line=line_all.replace('\x00', '').split(";")
答案 9 :(得分:1)
我得到了同样的错误。将文件保存为UTF-8并且有效。
答案 10 :(得分:1)
我在打开从Web服务生成的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...
声明: 请注意,这会覆盖原始数据。确保您有备份副本。你被警告了!
答案 11 :(得分:0)
对于所有那些'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'模式打开文件可以正常工作。我喜欢通用换行模式 - 它为我节省了很多麻烦。
答案 12 :(得分:0)
我在使用scrapy并获取压缩的csvfile而没有正确的中间件解压响应主体然后将其交给csvreader时遇到了这个问题。因此,该文件实际上不是一个csv文件,并相应地抛出了line contains NULL byte
错误。
答案 13 :(得分:0)
您是否尝试过使用gzip.open?
with gzip.open('my.csv', 'rb') as data_file:
我试图打开一个已压缩但扩展名为“ .csv”而不是“ csv.gz”的文件。在我使用gzip.open
之前,该错误一直显示答案 14 :(得分:-1)
一种情况是 - 如果CSV文件包含空行,则可能会显示此错误。在我们继续写或读之前,检查行是否必要。
for row in csvreader:
if (row):
do something
我通过在代码中添加此检查来解决我的问题。