Python CSV 오류 : 행에 NULL 바이트가 있습니다.


102

다음 코드를 사용하여 일부 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 바이트가 포함되어 있습니다.


무엇 않습니다 od -c처럼 첫 번째 줄의 모양을 말한다?
Ignacio Vazquez-Abrams

어떤 쿼리를 실행해야합니까? cat my.csv | od -c | 더? 그것으로 나는 얻는다 : 0000000 D epartment F
amil

CSV는 어떻게 생성됩니까? Excel에서 방언을 시도해 볼 수 있습니다. 그렇지 않으면 말을보고 : stackoverflow.com/questions/2753022/...
박사 jimbob

감사. 내 CSV가 아니며 불행히도 변경할 권한이 없습니다. Excel로 생성되어 CSV (boo)로 저장되었다고 생각합니다. 방언은 좋은 생각처럼 들립니다. 시도해 볼게요!
AP257 2010

실제로 CSV로 저장된 경우 작동합니다. 내가 가끔 찾는 한 가지는 CSV로 가장하는 TSV (탭으로 구분 된) 파일이므로 '\ t'구분 기호를 설정해 볼 수 있습니다. Excel 파일로 저장하고 확장자가 CSV로 변경되면 방언이 작동하지 않습니다. 이 경우 유일한 옵션은 Excel을 사용하여 사본을 적절한 CSV로 저장하는 것입니다.
Thomas K

답변:


104

@ 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 파일처럼 보입니까?


매우 상세한 도움을 주셔서 감사합니다. 파일에 \ x00 문자가 많이 있습니다 (질문에 대한 편집 참조). 텍스트 편집기에서는 완벽하게 합리적인 CSV 파일처럼 보이기 때문에 이상합니다.
AP257 2010

1
@ AP257 : '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1OLE2 복합 문서 파일 (예 : Excel 97-2003 .XLS 파일)을 나타내는 "서명"입니다 . 나는 "텍스트 편집기에서 그것은 완전히 합리적인 CSV 파일처럼 보인다"는 것을 완전히 믿을 수 없다는 것을 알게되었다 . 다른 파일, 유효한 CSV 파일, 다른 폴더 나 다른 컴퓨터 또는 다른 시간에보고 있었을 것입니다. 당신의 참고 od출력은 XLS 파일에서이 아니었다.
John Machin

8
@ AP257 :이 답변을 받아들이지 않은 특별한 이유가 있습니까?
John Machin 2011 년

작동하지만 CSV를 필터링하고 csv.reader직접 전달할 수있는 파일과 유사한 객체를 사용하여 즉시 가능하고 멋져 야합니다 .
gerrit

1
fo.write(data.replace('\x00', ''))fo.write(data.replace(b'\x00', b''))? 여기 파이썬 3.6 ...
Boern

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

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


내 경우에 대해 풀면 null은 '\ 0'값이었습니다. 감사.
요압 멘데스

19

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


13

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

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


7
해당 모듈을 지적 해 주셔서 감사합니다. 흥미롭게도 나는 그것을 다운로드하고 저자 가이 질문에 대한 최고 댓글이기도 한 @John_Machin 다름 아닌 것을 알았습니다.
Evan

11

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

7

존재하지 않는 척하고 싶다면 생성기를 인라인하여 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))

2

왜 이런 짓을하는?

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


@ AP257 : "도움이 안돼"? 무슨 뜻이야? 특정 오류 메시지가 있습니까?
S.Lott

1
@ S.Lott : 그가 전과 같은 답을 얻었음을 의미합니다. 현실은 그가 카멜레온 또는 shapeshifter 파일을 다루고 있다는 것입니다. ... 그가 그것을 od텍스트 편집기로 덤프 하거나 볼 때 그것은 완벽하게 정상적인 CSV 파일처럼 보입니다. 그러나 그가 Python repr ()로 처음 몇 바이트를 덤프하면 Excel .XLS 파일 (CSV 확장자를 갖도록 이름이 바뀜)처럼됩니다.
John Machin

@John Machin : "Excel .XLS 파일 (CSV 확장자를 갖도록 이름이 변경되었습니다") 전혀 처리 할 수 ​​없다는 것이 이해가됩니다.
S.Lott

1
@ S.Lott : 그 내용으로 csv 모듈이 그것을 처리 할 수 ​​없다는 것이 이치에 맞습니다. 그러나 xlrd 모듈은이를 처리 할 수 ​​있습니다. 실제로 입력이 이름이있는 파일이면 어느 모듈도 입력 파일의 이름에서 어떤 것도 유추하지 않습니다.
John Machin

1
@John Machin : "두 모듈 모두 입력 파일의 이름에서 어떤 것도 유추하지 않습니다." 진실. 내 애플리케이션 프레임 워크는 그 사실에 달려 있습니다. 사람들이 실수 ( "거짓말")를하기 때문에 파일 이름이 어떤 의미도 있다고 믿지 않습니다. 그래서 우리는 한 번의 클릭까지 여러 대안을 확인해야합니다.
S.Lott


2

csv 리더 대신 문자열에 대한 읽기 파일 및 분할 기능을 사용합니다.

lines = open(input_file,'rb') 

for line_all in lines:

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

1

같은 오류가 발생했습니다. 파일을 UTF-8로 저장하고 작동했습니다.


1
동일한 오류 메시지가 표시 될 수 있지만 원인은 다를 수 있습니다. 원래 UTF-16 (메모장에서 "유니 코드"라고 부르는 것)으로 저장했을 것입니다.
John Machin 2011

1

OpenOffice Calc로 CSV 파일을 만들 때 이런 일이 발생했습니다. 나중에 Calc로 편집하더라도 텍스트 편집기에서 CSV 파일을 만들 때 발생하지 않았습니다.

텍스트 편집기에서 Calc에서 만든 파일의 데이터를 새 편집기에서 만든 파일로 복사하여 붙여 넣어 문제를 해결했습니다.


1

빈 헤더에 NULL 바이트를 삽입 한 웹 서비스에서 생성 된 CSV를 여는 데 동일한 문제가 발생했습니다. 파일을 정리하기 위해 다음을 수행했습니다.

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

모든 'rU'파일 모드 싫어하는 사람 : 'rb'파일 모드를 사용하는 Mac의 Windows 컴퓨터에서 CSV 파일을 열려고 시도했는데 csv 모듈에서이 오류가 발생했습니다.

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

'rU'모드에서 파일을 열면 정상적으로 작동합니다. 저는 보편적 인 줄 바꿈 모드를 좋아합니다. 그것은 저에게 많은 번거 로움을 덜어줍니다.


0

스크래피를 사용하고 csvreader에 전달하기 전에 응답 본문을 압축 해제하는 올바른 미들웨어없이 압축 된 csvfile을 가져올 때이 문제가 발생했습니다. 따라서 파일은 실제로 csv 파일이 아니므로 line contains NULL byte그에 따라 오류가 발생했습니다.


0

gzip.open을 사용해 보셨습니까?

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

압축되었지만 'csv.gz'대신 '.csv'확장자를 가진 파일을 열려고했습니다. 이 오류는 gzip.open을 사용할 때까지 계속 표시되었습니다.


-1

한 가지 경우는-CSV 파일에 빈 행이 포함되어 있으면이 오류가 나타날 수 있습니다. 쓰기 또는 읽기를 진행하기 전에 행 확인이 필요합니다.

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

이 수표를 코드에 추가하여 문제를 해결했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.