[python] 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은 .csv로 부적절하게 저장된 Excel 파일 일 수 있다고 제안하는 것 같습니다. 파이썬에서이 문제를 해결할 수있는 방법이 있습니까?

== 업데이트 ==

아래 @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 바이트가 포함되어 있습니다.



답변

@ S.Lott가 말했듯이, ‘rU’모드가 아닌 ‘rb’모드에서 파일을 열어야합니다. 그러나 그것은 현재 문제를 일으키지 않을 수 있습니다. 내가 아는 한 ‘rU’모드를 사용 \r하면 데이터에 포함 되어 있으면 엉망이 되지만 다른 드라마는 발생하지 않습니다. 또한 여러 파일 (모두 ‘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출력 (또는 출력) \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()

그런데 텍스트 편집기로 파일 (마지막 몇 줄 포함)을 보셨습니까? 실제로 다른 파일 ( “NULL byte”예외 없음)과 같은 합리적인 CSV 파일처럼 보입니까?


답변

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

이것은 나를 위해 작동합니다.


답변

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 파일의 디렉토리입니다.


답변

나도이 문제에 부딪혔다. Python csv모듈을 사용하여 MS Excel에서 만든 XLS 파일을 읽고 NULL byte오류가 발생했습니다. MS Excel 스프레드 시트 파일에서 데이터를 읽고 서식을 지정하기위한 xlrd Python 모듈을 둘러 보았습니다 . xlrd모듈을 사용하면 파일을 제대로 읽을 수있을뿐만 아니라 이전에는 할 수 없었던 방식으로 파일의 여러 부분에 액세스 할 수도 있습니다.

도움이 될 거라고 생각했습니다.


답변

소스 파일의 인코딩을 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)


답변

존재하지 않는 척하고 싶다면 생성기를 인라인하여 null 값을 필터링 할 수 있습니다. 물론 이것은 null 바이트가 실제로 인코딩의 일부가 아니며 실제로 일종의 잘못된 아티팩트 또는 버그라고 가정합니다.

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


답변

왜 이런 짓을하는?

 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’플래그로 열어야합니다.