web-dev-qa-db-fra.com

"La ligne contient l'octet NULL" dans le lecteur CSV (Python)

J'essaie d'écrire un programme qui examine un fichier .CSV (input.csv) et ne réécrit que les lignes commençant par un certain élément (corrected.csv), comme indiqué dans un fichier texte (output.txt).

Voici à quoi ressemble mon programme:

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)

Malheureusement, je continue à avoir cette erreur et je n'ai aucune idée de ce dont il s'agit.

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

Crédit à toutes les personnes ici même pour m'amener à ce point.

65
James Roseman

J'ai résolu un problème similaire avec une solution plus simple:

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

La clé utilisait le module de codecs pour ouvrir le fichier avec le codage UTF-16, il y a beaucoup plus de codages, vérifiez la documentation .

53
K. David C.

Je suppose que vous avez un octet NUL dans input.csv. Vous pouvez tester cela avec

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

si tu fais,

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

peut vous aider autour de cela. Ou cela peut indiquer que vous avez utf16 ou quelque chose d '«intéressant» dans le fichier .csv.

53
retracile

Vous pouvez simplement inclure un générateur pour filtrer les valeurs NULL si vous voulez prétendre qu'elles n'existent pas. Bien sûr, cela suppose que les octets nuls ne font pas vraiment partie de l'encodage et constituent en réalité une sorte d'artefact ou de bogue erroné.

Voir le (line.replace('\0','') for line in f) ci-dessous, vous voudrez probablement aussi ouvrir ce fichier en utilisant le 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)
6
woot

Cela vous indiquera quelle ligne est le problème.

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

Peut-être ceci de daniweb serait utile:

Je reçois cette erreur en lisant un fichier csv: "Erreur d’exécution! Line contient un octet NULL". Une idée sur la cause première de cette erreur?

...

Ok, je l’ai eu et je pensais publier la solution. Tout simplement encore m'a causé chagrin ... Le fichier utilisé a été enregistré au format .xls au lieu du fichier .csv Did not attraper cela parce que le nom du fichier lui-même avait l'extension .csv alors que le type était encore .xls

5
Steven Rumbalski

Si vous voulez remplacer les NULL par quelque chose, vous pouvez le faire:

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

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

Transformer mon environnement linux en un environnement UTF-8 complet et net est ce qui m’a poussé à comprendre… ... Essayez ceci dans votre ligne de commande:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
1
Philippe Oger

J'ai récemment résolu ce problème et dans mon cas, c'est un fichier compressé que j'essayais de lire. Vérifiez d'abord le format du fichier. Ensuite, vérifiez que le contenu correspond à l’extension. 

1
Daniel Lee

pandas.read_csv gère maintenant les différents encodages UTF en lecture/écriture et peut donc traiter directement avec des octets nuls

data = pd.read_csv(file, encoding='utf-16')

voir https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

0

Une manière délicate:

Si vous développez sous Lunux, vous pouvez utiliser toute la puissance de 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)    

La solution la plus efficace pour les gros fichiers.

Vérifié pour Python3, Kubuntu

0
SergO