118 votes

Erreur CSV Python: la ligne contient l'octet NULL

Je travaille avec certains fichiers CSV, avec le code suivant:

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

Et lorsqu'un fichier est de lancer cette erreur:

file my.csv, line 1: line contains NULL byte

Que puis-je faire? Google semble suggérer que c'est peut être un fichier Excel qui a été enregistré comme une .csv mal. Est il possible que je peux contourner ce problème en Python?

== Mise à JOUR ==

Suivant @JohnMachin de commentaire ci-dessous, j'ai essayé d'ajouter ces lignes dans mon 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')

Et c'est le résultat que j'ai obtenu:

'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00\x00\x00\x00\x00\x00\x00\ .... <snip>
8
13834

Si le fichier contient en effet des NUL octets.

120voto

John Machin Points 39706

@S. Lott dit, vous devriez être à l'ouverture de vos fichiers dans 'rb', pas 'rU' mode. Cependant qui ne peut PAS être la cause de votre problème actuel. Autant que je sache, à l'aide de 'rU' mode de désordre vous si il y a incorporé \r dans les données, mais pas causer d'autres drames. Je note également que vous disposez de plusieurs fichiers (tous ouvert avec 'rU' ??) mais un seul à l'origine du problème.

Si le module csv dit que vous avez un "NULL" (stupide message devrait être "NUL") octet dans le fichier, alors vous devez vérifier ce qui se trouve dans votre fichier. Je voudrais vous suggérer de le faire même si l'utilisation de 'rb' rend le problème.

repr() est (ou se veut) le débogage de votre ami. Il va montrer sans ambiguïté que vous avez, dans une plate-forme indépendante de la mode (ce qui est utile pour les accompagnateurs qui ne savent pas ce qu' od est ou n'). Faire cela:

print repr(open('my.csv', 'rb').read(200)) # dump 1st 200 bytes of file

et soigneusement copier/coller (ne pas retaper) le résultat dans une édition de votre question (non pas dans un commentaire).

Notez également que si le fichier est vraiment louche par exemple, pas de \r ou \n à une distance raisonnable à partir du début du fichier, le numéro de la ligne signalée par reader.line_num (unhelpfully) 1. Trouver l'emplacement de la première \x00 est (le cas échéant)

data = open('my.csv', 'rb').read()
print data.find('\x00')

et assurez-vous que vous dump au moins ce nombre d'octets avec les repr ou od.

Qu'est - data.count('\x00') dites-vous? Si il y a beaucoup, vous voudrez peut-être faire quelque chose comme

for i, c in enumerate(data):
    if c == '\x00':
        print i, repr(data[i-30:i]) + ' *NUL* ' + repr(data[i+1:i+31])

de sorte que vous pouvez voir NUL octets dans le contexte.

Si vous pouvez voir \x00 à la sortie (ou \0 votre od -c sortie), alors vous avez certainement NUL byte(s) dans le fichier, et vous aurez besoin de faire quelque chose comme ceci:

fi = open('my.csv', 'rb')
data = fi.read()
fi.close()
fo = open('mynew.csv', 'wb')
fo.write(data.replace('\x00', ''))
fo.close()

En passant, avez-vous regardé le fichier (y compris les dernières lignes) avec un éditeur de texte? Faut-il réellement ressembler à un raisonnable fichier CSV comme les autres (pas de "octet NULL" exception) des fichiers?

22voto

macdonjo Points 478

Le lire comme UTF-16 était aussi mon problème.

Voici mon code qui a fini par fonctionner:

 f=codecs.open(location,"rb","utf-16")
csvread=csv.reader(f,delimiter='\t')
csvread.next()
for row in csvread:
    print row
 

Où location est le répertoire de votre fichier csv.

14voto

ayaz Points 6910

Je suis tombé sur ce problème. À l'aide de l'Python csv module, j'ai essayé de lire un fichier XLS créés dans MS Excel et en cours d'exécution dans l' NULL byte d'erreur que vous aviez. J'ai regardé autour et a trouvé le xlrd module Python pour la lecture et la mise en forme des données de feuille de calcul MS Excel fichiers. Avec l' xlrd module, je ne suis pas seulement en mesure de lire le fichier correctement, mais je peux également accéder à de nombreuses parties différentes du fichier dans un sens, je ne pouvais pas avant.

J'ai pensé qu'il pourrait vous aider.

11voto

Patrick Halley Points 21

La conversion de l'encodage du fichier source d'UTF-16 à UTF-8 résout mon problème.

Comment convertir un fichier en utf-8 en 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)
 

2voto

Xavier Combelle Points 3398

apparemment, il s’agit d’un fichier XLS et non d’un fichier CSV, comme http://www.garykessler.net/library/file_sigs.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X