python null byte_Python CSV错误:行包含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\....

8

13834

因此该文件确实包含NUL字节。

od -c表示第一行是什么样的?

我应该运行什么查询,例如cat my.csv | od -c |更多 ?得到的结果是:0000000 D e p a r t m e n t F a m i l

CSV是如何生成的?通过excel,您可以尝试方言。否则看看说:stackoverflow.com/questions/2753022/

谢谢。它不是我的CSV,很遗憾,我没有更改它的能力。我认为它已创建为Excel,并另存为CSV(boo)。方言听起来不错,请尝试一下!

如果实际将其另存为CSV,则应该可以使用。我有时发现的一件事是伪装成CSV的TSV(制表符分隔)文件,因此您可以尝试设置 t的分隔符。如果将其另存为Excel文件,并且扩展名更改为CSV,则没有任何方言将起作用。我认为在这种情况下,您唯一的选择是使用Excel将副本另存为适当的CSV。

我讲得太早了:甚至还有一个Python包可以读取xls文件,称为xlrd。不过,不知道它的运作情况如何。 python-excel.org

@ AP257:Ignacio表示文件中的第一行,而不仅仅是ods输出的第一行(仅16个字节)。您需要转储更多;看我的答案。

正如@ S.Lott所说,您应该以" rb"模式而不是" rU"模式打开文件。但是,这可能不会引起您当前的问题。据我所知,如果在数据中嵌入,则使用" 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的位置(如果有)

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字节"例外)一样合理的CSV文件吗?

非常感谢您提供的非常详细的帮助。该文件中有许多 x00字符(请参阅问题解答),这很奇怪,因为在文本编辑器中,它看起来像是一个非常合理的CSV文件。

@ AP257:\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1是表示OLE2复合文档文件的"签名",例如Excel 97-2003 .XLS文件。我发现"在文本编辑器中,它看起来像是一个完全合理的CSV文件",这简直令人难以置信。您必须一直在另一个文件夹或另一台计算机上或其他时间查看其他文件,有效的CSV文件。请注意,您的od输出不是来自XLS文件的。

@ AP257:您尚未接受此答案的任何特定原因?

可行,但应该可以并且可以通过过滤CSV的类似文件的对象即时运行,并且可以直接传递给csv.reader。

我认为od是此答案中os的错字。

@lin_bug od是unix实用程序...名称是"八进制转储"的缩写

fo.write(data.replace(\x00, ))不应该是fo.write(data.replace(b\x00, b))吗? Python 3.6在这里...

将其读取为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文件的目录。

data_initial = open("staff.csv","rb")

data = csv.reader((line.replace('\0','') for line in data_initial), delimiter=",")

这对我有用。

对于我的情况,解决的是 0值。谢谢。

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

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

感谢您指出该模块。有趣的是,我去下载了它,发现作者就是@John_Machin,他也是这个问题的最高评论。

将源文件的编码从UTF-16转换为UTF-8解决了我的问题。

如何在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)

如果要假装不存在空值,则可以内联生成器以过滤掉空值。当然,这是假定空字节实际上不是编码的一部分,而是某种错误的工件或错误。

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

代替csv阅读器,我对字符串使用read文件和split函数:

lines = open(input_file,'rb')

for line_all in lines:

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

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

不一定,但是是的,这可能是一个原因。当我尝试解析Excel从XLSX文件保存的CSV文件时,确实收到了此错误。

使用此幻数,其原因XLSX具有不同的幻数

你为什么做这个?

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.

谢谢,但没有帮助...

@ AP257:"不需要帮助"吗?意味着什么?任何特定的错误消息?

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

@John Machin:"一个Excel .XLS文件(该文件已重命名为CSV扩展名",这使得它根本无法处理。

@ S.Lott:使用该内容,csv模块无法处理该内容;但是xlrd模块可以处理它。明智地,如果输入确实是带有名称的文件,则这两个模块都不从输入文件的名称推断任何内容。

@John Machin:"这两个模块都不从输入文件的名称中推断出任何东西"。真正。我的应用程序框架取决于这一事实。我们不相信文件名意味着任何东西,因为人们会犯错误("谎言")。因此,我们必须检查一堆替代方案,直到单击一次。

我只是对" csv"文件有一个有趣的经验,该文件在Notepad ++中看起来非常正常,但是在Python 2.7.9中使用CSV模块读取该文件时却出现了空字节错误。事实证明,Notepad ++正在检测unicode编码,并慷慨/有帮助地向我隐藏了它,而CSV需要ASCII。看来这不是使NP ++原始打开的一种方法,但是至少它可以让我转换为ANSI,然后可以使用CSV读取它。的确有警告,不要假设NP ++中的明显OKness可以证明没有非ASCII数据。

Python 2必需的模式"rb"。相反,Python 3需要模式"r"。

我遇到了同样的错误。将文件保存在UTF-8中,可以正常工作。

您可能会收到相同的错误消息,但原因可能有所不同-您可能最初将其保存为UTF-16(记事本称为" Unicode")。

打开从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...

免责声明:

请注意,这会覆盖您的原始数据。确保您拥有它的备份副本。你被警告了!

当我使用OpenOffice Calc创建CSV文件时,这发生在我身上。当我在文本编辑器中创建CSV文件时,即使以后使用Calc编辑它,也没有发生。

通过将文本从Calc创建的文件复制粘贴到新的编辑器创建的文件中,我解决了我的问题。

您是否尝试过使用gzip.open?

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

我试图打开一个已压缩但扩展名为" .csv"而不是" csv.gz"的文件。在我使用gzip.open之前,此错误一直显示

对于所有那些" rU"文件模式的讨厌者:我只是尝试从Mac上的Windows计算机上使用" rb"文件模式打开CSV文件,而我从csv模块中得到了此错误:

Error: new-line character seen in unquoted field - do you need to

open the file in universal-newline mode?

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

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

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

for row in csvreader:

if (row):

do something

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值