2010-11-12 45 views
77

我与一些CSV文件时,用下面的代码:Python的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。有什么办法可以解决Python中的这个问题吗?

== == 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

“od -c”表示第一行看起来像什么? – 2010-11-12 15:22:15

+0

我应该运行什么查询,如cat my.csv | od -c |更多 ?我得到:0000000 D e p a r t m e n t F a m i l – AP257 2010-11-12 15:35:13

+0

CSV是如何生成的?从excel中,你可以尝试一种方言。否则看看说:http://stackoverflow.com/questions/2753022/python-finding-unicode-ascii-problems – 2010-11-12 15:51:37

回答

1

你为什么要这么做?

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

If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference.

+2

谢谢,但没有帮助... – AP257 2010-11-15 17:27:35

+0

@ AP257:“没有帮助”?意味着什么?任何特定的错误消息? – 2010-11-15 19:40:55

+1

@ S.Lott:意味着他得到和以前一样的答案。现实情况是,他正在处理一个变色龙或shapeshifter文件...当他用'od'转储它或在文本编辑器中查看它时,它看起来像一个完全正常的CSV文件。但是,当他用Python repr()转储前几个字节时,它就像一个Excel .XLS文件(它已被重命名为具有CSV扩展名)。 – 2010-11-15 22:01:18

90

正如@美国洛特说,你应该在 'RB' 模式打开你的文件,而不是'儒的模式。但是,这可能不会导致您目前的问题。据我所知,如果在数据中嵌入\r,但使用'rU'模式会让你感到不适,但不会导致其他任何电视剧。我还注意到,你有几个文件(都用'rU'??打开),但只有一个导致问题。

如果csv模块说你有一个“空”(愚蠢的消息,应该是“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是(如果有的话)做

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(或\0od -c输出),那么你肯定有在文件中NULL字节(S),你需要做这样的事情:

fi = open('my.csv', 'rb') 
data = fi.read() 
fi.close() 
fo = open('mynew.csv', 'wb') 
fo.write(data.replace('\x00', '')) 
fo.close() 

顺便说一下,你是否用文本编辑器查看过文件(包括最后几行)?它实际上看起来像一个合理的CSV文件(没有“NULL字节”异常)文件吗?

+0

非常感谢您提供非常详细的帮助。文件中有很多\ x00个字符(请参阅编辑问题) - 这很奇怪,因为在文本编辑器中它看起来像一个完全合理的CSV文件。 – AP257 2010-11-15 17:35:09

+1

@ AP257:''\ xd0 \ xcf \ x11 \ xe0 \ xa1 \ xb1 \ x1a \ xe1'是表示OLE2复合文档文件的“签名”。一个** Excel 97-2003 .XLS文件**。我发现“在文本编辑器中,它看起来像一个完全合理的CSV文件”是**完全不可信**。您必须一直在查看另一个文件夹,有效的CSV文件,另一个文件夹或另一台计算机上或其他某个时间。请注意,您的'od'输出不是来自XLS文件。 – 2010-11-15 21:48:04

+7

@ AP257:您还没有接受此答案的任何特定原因? – 2011-01-24 05:14:02

2

appparently这是一个XLS文件,而不是一个CSV文件作为http://www.garykessler.net/library/file_sigs.html确认

+0

不一定,但是,这可能是一个原因。当我尝试解析由Excel从XLSX文件保存的CSV文件时,我确实收到了此错误。 – Cerin 2015-01-22 18:29:20

+0

有了这个神奇的数字,它的原因是XLSX有不同的幻数 – 2015-01-24 14:09:11

12

我碰上了这个问题为好。使用Python csv模块,我试图读取在MS Excel中创建的XLS文件,并且遇到您遇到的NULL byte错误。我环顾四周,发现xlrd Python模块用于从MS Excel电子表格文件中读取和格式化数据。使用xlrd模块,我不仅可以正确读取文件,还可以以前所未有的方式访问文件的许多不同部分。

我认为这可能对你有帮助。

+6

感谢您指出该模块。有趣的是,我去下载并注意到作者是@John_Machin,也是对这个问题的最高评论。 – Evan 2012-03-19 23:28:31

1

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

+1

您可能得到了相同的错误信息,但原因可能会有所不同 - 您可能最初将其保存为UTF-16(记事本称为“Unicode”)。 – 2011-11-29 07:48:13

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) 
2

相反CSV阅读我用读文件和拆分功能字符串:

lines = open(input_file,'rb') 

for line_all in lines: 

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

这发生在我身上时,我创建了一个CSV与OpenOffice的Calc的文件。当我在文本编辑器中创建CSV文件时,即使我之后使用Calc进行编辑,也不会发生这种情况。

我解决了我的问题,在我的文本编辑器中将我的Calc创建的文件中的数据粘贴到新的编辑器创建的文件中。

1

我有同样的问题,打开一个CSV服务产生的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... 

免责声明: 请注意,这将覆盖原来的数据。确保你有它的备份副本。你被警告了!

0

对于所有那些'儒的FILEMODE仇敌:我只是想从Windows机器在Mac上打开一个CSV文件与“RB” FILEMODE和我从csv模块这个错误:

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

以'rU'模式打开文件可以正常工作。我喜欢通用换行模式 - 它为我节省了很多麻烦。

15

把它看作UTF-16也是我的问题。

这里是我的代码,结束了工作:

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

其中位置是您的CSV文件的目录。

0

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

4

如果你想假装它们不存在,你可以直接插入一个生成器来过滤出空值。当然,这是假设空字节不是编码的真正部分,实际上是某种错误的工件或错误。

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

这对我的作品。

+0

解决了我的情况,null是'\ 0'值。谢谢。 – 2017-02-12 02:44:26

-1

一种情况是 - 如果CSV文件包含空行,则可能会显示此错误。在我们继续写或读之前检查行是必要的。

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

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

相关问题