Ошибка CSV Python: строка содержит 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?
== UPDATE ==
Следуя комментарию @JohnMachin ниже, я попытался добавить эти строки в свой script:
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 байты.
Ответы
Ответ 1
Как следует из @S.Lott, вы должны открывать свои файлы в режиме "rb", а не в режиме "rU". Однако это НЕ может быть причиной вашей текущей проблемы. Насколько я знаю, использование режима "rU" может испортить вас, если в данных встроены \r
, но не вызывают никаких других драм. Я также отмечаю, что у вас есть несколько файлов (все они открыты с помощью 'rU'??), но только один из них вызывает проблему.
Если модуль csv говорит, что у вас есть "NULL" (глупое сообщение должно быть "NUL" ) байт в вашем файле, тогда вам нужно проверить, что находится в вашем файле. Я бы предположил, что вы это сделаете, даже если использование "rb" заставляет проблему уйти.
repr()
является (или хочет быть) вашим отладочным другом. Он однозначно покажет то, что у вас есть, на платформе независимой моды (что полезно для помощников, которые не знают, что такое od
). Сделайте это:
print repr(open('my.csv', 'rb').read(200)) # dump 1st 200 bytes of file
и аккуратно скопируйте/вставьте (не перепечатывайте) результат в редактирование вашего вопроса (не в комментарий).
Также обратите внимание, что если файл действительно неудобен, например. no\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
в выводе (или \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 файл, такой как другой (без исключений)?
Ответ 2
Чтение его как UTF-16 также было моей проблемой.
Здесь мой код, который закончился:
f=codecs.open(location,"rb","utf-16")
csvread=csv.reader(f,delimiter='\t')
csvread.next()
for row in csvread:
print row
Где местоположение - это каталог вашего файла csv.
Ответ 3
data_initial = open("staff.csv", "rb")
data = csv.reader((line.replace('\0','') for line in data_initial), delimiter=",")
Это работает для меня.
Ответ 4
Я столкнулся с этой проблемой. Используя модуль Python csv
, я пытался прочитать файл XLS, созданный в MS Excel, и запущенный в ошибке NULL byte
, которую вы получали. Я огляделся и нашел xlrd Модуль Python для чтения и форматирования данных из файлов электронной таблицы MS Excel. С модулем xlrd
я могу не только правильно прочитать файл, но также могу получить доступ ко многим различным частям файла так, как раньше не мог.
Я подумал, что это может вам помочь.
Ответ 5
Преобразование кодировки исходного файла из UTF-16 в UTF-8 решает мою проблему.
Как преобразовать файл в utf-8 в 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)
Ответ 6
Вы можете просто встроить генератор, чтобы отфильтровать нулевые значения, если вы хотите притвориться, что они не существуют. Конечно, это предполагает, что нулевые байты на самом деле не являются частью кодировки и действительно являются своего рода ошибочным артефактом или ошибкой.
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))
Ответ 7
Зачем ты это делаешь?
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 на платформах, где это имеет значение.
Ответ 8
возможно, это файл XLS, а не файл CSV как http://www.garykessler.net/library/file_sigs.html подтвердить
Ответ 9
Вместо чтения csv я использую read file и функцию split для строки:
lines = open(input_file,'rb')
for line_all in lines:
line=line_all.replace('\x00', '').split(";")
Ответ 10
Я получил ту же ошибку. Сохранял файл в UTF-8, и он работал.
Ответ 11
Это случилось со мной, когда я создал файл CSV с OpenOffice Calc. Это не произошло, когда я создал CSV файл в текстовом редакторе, даже если позже я его отредактировал с помощью Calc.
Я решил проблему, скопировав в текстовом редакторе данные из моего созданного Calc файла в новый файл, созданный редактором.
Ответ 12
У меня была такая же проблема, открывая 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...
Отказ от ответственности:
Имейте в виду, что это перезаписывает ваши исходные данные. Убедитесь, что у вас есть резервная копия. Вы были предупреждены!
Ответ 13
Для всех этих ненавистных читателей файловой системы rU: я просто попытался открыть файл CSV с компьютера Windows на Mac с файловым модемом "rb", и я получил эту ошибку из модуля csv:
Error: new-line character seen in unquoted field - do you need to
open the file in universal-newline mode?
Открытие файла в режиме "rU" отлично работает. Мне нравится универсальный режим новой строки - это избавляет меня от хлопот.
Ответ 14
Я столкнулся с этим при использовании scrapy и извлечении zs файла без необходимости иметь правильное промежуточное программное обеспечение, чтобы разархивировать тело ответа перед передачей его в csvreader. Следовательно, файл не был действительно csv файлом и соответственно отклонил ошибку line contains NULL byte
.
Ответ 15
Вы пытались использовать gzip.open?
with gzip.open('my.csv', 'rb') as data_file:
Я пытался открыть файл, который был сжат, но имел расширение ".csv" вместо "csv.gz". Эта ошибка продолжала появляться, пока я не использовал gzip.open
Ответ 16
В одном случае - если CSV файл содержит пустые строки, эта ошибка может появиться. Проверка строки необходима, прежде чем мы начнем писать или читать.
for row in csvreader:
if (row):
do something
Я решил проблему, добавив эту проверку в код.