2011-10-25 13 views
49

Sto provando a scrivere un programma che guarda un file .CSV (input.csv) e riscrive solo le righe che iniziano con un determinato elemento (corrected.csv), come elencato in un file di testo (output.txt)."Riga contiene byte NULL" nel lettore CSV (Python)

Questo è ciò che il mio programma si presenta come in questo momento:

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) 

Purtroppo, continuo a ricevere questo errore, e non ho idea di cosa si tratta.

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 

credito a tutte le persone here per anche per farmi a questo punto.

+0

Solo una supposizione, ma suona come il file input.csv contiene una riga vuota (MEBE alla fine?). Prova a cercare nel file csvParser.py per quel testo di eccezione. –

+0

In realtà ho appena passato il file input.csv e mi sono liberato di ogni spazio vuoto ... ancora senza fortuna (stesso errore). –

+0

Per individuare il numero di riga, suggerisco di introdurre una variabile contatore e di incrementarla all'interno del ciclo '' for row in reader''. – codeape

risposta

38

Ho risolto un problema simile con una soluzione più semplice:

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

La chiave era usando il modulo codecs per aprire il file con la codifica UTF-16, ci sono molte più codifiche, controlla lo documentation.

+0

Grazie per aver risposto! Grazie anche per la risorsa, questo ha molto senso ora. –

+2

Ho avuto lo stesso problema con un file CSV creato da LibreOffice, che era stato originariamente aperto da un file .xls di Excel. Per qualche ragione, LibreOffice aveva salvato il file CSV come UTF-16. Puoi vedere guardando i primi 2 byte del file, se è FF FE, allora è un buon indicatore che sia UTF-16 –

+4

Nota che se il tuo file contiene dati UTF-16 * al di fuori dell'intervallo ASCII * 'csv .reader() 'non sarà in grado di gestirlo, e otterrete invece' UnicodeEncodeError's. –

42

Suppongo che tu abbia un byte NUL in input.csv. È possibile verificare che, con

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

se lo fai,

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

può ottenere intorno a quello. Oppure potrebbe indicare che hai utf16 o qualcosa di 'interessante' nel file .csv.

+2

+1 alla ricerca di byte NULL nel file ... non opportunamente ora il mio file 'corrected.csv' ora viene letto in giapponese ... –

+0

Suoni come il tuo .csv non è in ascii. Penso che un ulteriore aiuto richiederà un po 'più di informazioni sul contenuto effettivo di .csv. Hai provato ad aprirlo in un editor di testo come Vim o Blocco note? O eseguendo 'file input.csv' per identificare il tipo di file? – retracile

+0

L'ho aperto nel blocco note e sembra a posto. Come dovrebbe essere un CSV? Si legge come su Google Analytics, ma con enormi schede tra i dati. –

4

Questo ti dirà quale sia il problema.

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 

Forse this da daniweb sarebbe utile:

I'm getting this error when reading from a csv file: "Runtime Error! line contains NULL byte". Any idea about the root cause of this error?

...

Ok, I got it and thought I'd post the solution. Simply yet caused me grief... Used file was saved in a .xls format instead of a .csv Didn't catch this because the file name itself had the .csv extension while the type was still .xls

+0

'Traceback (ultima chiamata ultima): File" C: \ Python32 \ Sample Program \ csvParser.py ", riga 17, in stampa ('csv soffocato sulla linea% s'% (i + 1)) NameError: nome 'i' non definito ' –

+0

Ok. Quindi sta soffocando sulla primissima linea. Esegui questo e pubblica ciò che vedi: 'print (open ('input.csv', 'r'). Readlines() [0])' –

+0

Qualcosa di funky ... ma è in esecuzione. 'ÿþ /'

4

Si potrebbe semplicemente inline un generatore per filtrare i valori nulli se si vuole far finta che non esistano. Ovviamente questo presuppone che i byte null non facciano realmente parte della codifica e siano in realtà una sorta di artefatto o bug errati.

Vedere il numero (line.replace('\0','') for line in f) di seguito, probabilmente si aprirà probabilmente il file utilizzando la modalità 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) 
+0

Grazie! Questo ha funzionato per i file dei risultati delle elezioni NC, che effettivamente (!) Utilizzano un byte null al posto di un byte "0" in una colonna. Vedi http://dl.ncsbe.gov/ENRS/resultsPCT20161108.zip – nealmcb

0

Ho risolto il problema di recente e nel mio caso si trattava di un file compresso che stavo cercando di leggere. Controlla prima il formato del file. Quindi controlla che il contenuto sia ciò a cui si riferisce l'estensione.

0

Trasformare il mio ambiente Linux in un ambiente UTF-8 completo e pulito ha fatto il trucco per me. Provare quanto segue nella riga di comando:

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

Un modo ingannevole:

Se si sviluppa sotto Lunux, è possibile utilizzare tutta la potenza di 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)  

Il più soluzione efficiente per file enormi.

Controllato per python3, Kubuntu