CSV阅读器(Python)中的“行包含NULL字节”


84

我正在尝试编写一个程序,该程序查看.CSV文件(input.csv)并仅重写以某个元素(corrected.csv)开头的行,如文本文件(output.txt)中所列。

这是我的程序现在的样子:

import csv

lines = []
with open('output.txt','r') as f:
    for line in f.readlines():
        lines.append(line[:-1])

with open('corrected.csv','w') as correct:
    writer = csv.writer(correct, dialect = 'excel')
    with open('input.csv', 'r') as mycsv:
        reader = csv.reader(mycsv)
        for row in reader:
            if row[0] not in lines:
                writer.writerow(row)

不幸的是,我一直收到此错误,而且我不知道它是什么。

Traceback (most recent call last):
  File "C:\Python32\Sample Program\csvParser.py", line 12, in <module>
    for row in reader:
_csv.Error: line contains NULL byte

感谢这里的所有人,甚至使我明白这一点。


只是一个猜测,但听起来您的input.csv文件包含空行(是末尾吗?)。尝试在csvParser.py文件中查找该异常文本。
山姆·阿克斯

实际上,我只是遍历了input.csv文件,摆脱了所有空白...仍然没有运气(相同的错误)。
詹姆斯·罗斯曼

为了查明行号,我建议您引入一个计数器变量,并在for row in reader循环中将其递增。
codeape 2011年

当程序本身无法执行时,我不确定应该怎么做。我尝试添加一个计数器,没有发现任何不同,只是相同的回溯错误。
詹姆士·罗斯曼

4
.csv中是否有NULL字节? open('input.csv').read().index('\0')如果这样做的话,将为您提供第一个的偏移量。
2011年

Answers:


66

我已经通过更简单的解决方案解决了类似的问题:

import codecs
csvReader = csv.reader(codecs.open('file.csv', 'rU', 'utf-16'))

关键是使用编解码器模块以UTF-16编码打开文件,还有很多编码,请查看文档


4
我从LibreOffice创建的CSV文件遇到了相同的问题,该文件最初是从Excel .xls文件打开的。由于某种原因,LibreOffice将CSV文件保存为UTF-16。您可以通过查看文件的前2个字节来判断,如果它是FF FE,那么就很好地表明它是UTF-16
Tom Dalton

4
请注意,如果文件包含ASCII范围之外的 UTF-16数据csv.reader()将无法处理它,UnicodeEncodeError而是显示s。
马丁·彼得斯

6
这只是引起了一个不同的错误,UnicodeError: UTF-16 stream does not start with BOM
Cerin

就我而言'utf-16le'
帕维尔Szczur

69

我猜你在input.csv中有一个NUL字节。你可以用

if '\0' in open('input.csv').read():
    print "you have null bytes in your input file"
else:
    print "you don't"

如果你这样做

reader = csv.reader(x.replace('\0', '') for x in mycsv)

可能会帮助您解决。否则可能表明您在.csv文件中有utf16或“有趣”的内容。


5
在文件中找到NULL字节时+1 ...不幸的是,现在我的'corrected.csv'文件现在以日语读取了...
James Roseman

听起来您的.csv不在ASCII中。我认为进一步的帮助将需要有关.csv实际内容的更多信息。您是否尝试过在像vim或记事本这样的文本编辑器中打开它?还是正在运行file input.csv以识别文件类型?
11

我已经在记事本中打开它,看起来不错。CSV应该是什么样子?它的读取方式与Google Analytics(分析)相同,但数据之间的标签很大。
詹姆斯·罗斯曼

该死...有什么办法可以用逗号替换制表符并且可以在Python程序中使用吗?
詹姆斯·罗斯曼

1
如果您的csv是制表符分隔的,则需要指定:reader = csv.reader(mycsv, delimiter='\t')。我想象到csv阅读器正在吞噬整个文件,以寻找逗号并一直到EOF。但是您肯定有编码问题。打开文件时,您需要指定编码。
史蒂芬·鲁姆巴尔斯基

11

如果您要用某些内容替换空值,可以执行以下操作:

def fix_nulls(s):
    for line in s:
        yield line.replace('\0', ' ')

r = csv.reader(fix_nulls(open(...)))

2
用空格代替null并不是一个好选择。为我工作,用空字符串替换
Marcelo Assis,2018年

我对您如何使用收益有疑问。鉴于这是一个循环,是否意味着它仍然会逐行读取文件,还是会立即将其加载到内存中?
mnsr

10

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

参见(line.replace('\0','') for line in f)下文,您可能还想使用mode打开该文件rb

import csv

lines = []
with open('output.txt','r') as f:
    for line in f.readlines():
        lines.append(line[:-1])

with open('corrected.csv','w') as correct:
    writer = csv.writer(correct, dialect = 'excel')
    with open('input.csv', 'rb') as mycsv:
        reader = csv.reader( (line.replace('\0','') for line in mycsv) )
        for row in reader:
            if row[0] not in lines:
                writer.writerow(row)

谢谢!这适用于NC选举结果文件,实际上确实(!)使用空字节代替一列中的“ 0”字节。参见dl.ncsbe.gov/ENRS/resultsPCT20161108.zip
nealmcb,2013年

7

这将告诉您问题所在。

import csv

lines = []
with open('output.txt','r') as f:
    for line in f.readlines():
        lines.append(line[:-1])

with open('corrected.csv','w') as correct:
    writer = csv.writer(correct, dialect = 'excel')
    with open('input.csv', 'r') as mycsv:
        reader = csv.reader(mycsv)
        try:
            for i, row in enumerate(reader):
                if row[0] not in lines:
                   writer.writerow(row)
        except csv.Error:
            print('csv choked on line %s' % (i+1))
            raise

或许,从daniweb将是有益的:

从csv文件读取时出现此错误:“运行时错误!行包含NULL字节”。关于此错误的根本原因有什么想法吗?

...

好的,我明白了,以为我会发布解决方案。只是让我感到悲痛...使用过的文件以.xls格式而不是.csv格式保存没有捕获到此文件,因为文件名本身仍具有.csv扩展名,而类型仍为.xls


1
Traceback (most recent call last): File "C:\Python32\Sample Program\csvParser.py", line 17, in <module> print ('csv choked on line %s' % (i+1)) NameError: name 'i' is not defined
詹姆斯·罗斯曼

好。然后在第一行就令人窒息。运行此命令,然后发布您看到的内容:print(open('input.csv', 'r').readlines()[0])
Steven Rumbalski 2011年

有点时髦...但是它正在运行。ÿþ/<这就是粘贴的全部内容(主要是块和数字)
James Roseman

1
也许您的csv并不是真正的csv。请参阅我的答案的后半部分。
史蒂芬·鲁姆巴尔斯基

哦,拍摄完全可以,我该如何解决?我也直接从Google Analytics(分析)中保存了它
James Roseman

2

一个棘手的方法:

如果您在Lunux下开发,则可以使用sed的所有功能:

from subprocess import check_call, CalledProcessError

PATH_TO_FILE = '/home/user/some/path/to/file.csv'

try:
    check_call("sed -i -e 's|\\x0||g' {}".format(PATH_TO_FILE), shell=True)
except CalledProcessError as err:
    print(err)    

大型文件的最有效解决方案。

检查Python3,Kubuntu


1

我最近解决了这个问题,在我的情况下,这是我尝试读取的压缩文件。首先检查文件格式。然后检查内容是否为扩展名所指。


1

将我的linux环境变成一个干净的完整UTF-8环境对我来说是个诀窍。在命令行中尝试以下操作:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

对我来说,也改用UTF-8解决了这个问题。在Windows上,我使用Notepad ++将格式从UTF16更改为UTF8。然后我打开与LibreOffice中钙的文件,清除多余的线条等等
尤瓦Harpaz

1

这个问题早就解决了,但是我遇到了这个答案,因为在读取CSV以在Keras和TensorFlow中作为训练数据进行处理时遇到了意外错误。

就我而言,这个问题要简单得多,值得我们注意。生成到CSV中的数据不一致,导致某些列完全丢失,这似乎最终也会引发此错误。

课程:如果您看到此错误,请验证数据是否按照您认为的样子进行!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.