पायथन 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 के रूप में सहेजा गया है। क्या पायथन में इस समस्या का कोई भी तरीका हो सकता है?

== अद्यतन ==

नीचे @ 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की तरह कहते हैं कि पहली पंक्ति दिखता है?
इग्नासियो वाज़क्वेज़-अब्राम्स

मुझे कौन सी क्वेरी चलाना चाहिए, बिल्ली my.csv जैसा कुछ | od -c | अधिक ? उस के साथ मैं मिलता है: 0000000 डी epartment एफ amil
AP257

CSV कैसे उत्पन्न होता है? एक्सेल से, आप एक बोली की कोशिश करने में सक्षम हो सकते हैं। अन्यथा कहने के लिए देखें: stackoverflow.com/questions/2753022/…
dr jimbob

धन्यवाद। यह मेरा CSV नहीं है, और दुर्भाग्य से मेरे पास इसे बदलने की शक्ति नहीं है। मुझे लगता है कि इसे एक्सेल के रूप में बनाया गया है और सीएसवी (बू) के रूप में सहेजा गया है। एक बोली एक अच्छे विचार की तरह लगती है - मैं कोशिश करूँगा कि!
16:25

यदि यह वास्तव में CSV के रूप में सहेजा गया है, तो इसे काम करना चाहिए। एक चीज जो मुझे कभी-कभी लगती है, वह है TSV (टैब अलग) फाइलें CSV के रूप में मुखर होती हैं, इसलिए आप '\ t' का सीमांकन करने का प्रयास कर सकते हैं। यदि इसे Excel फ़ाइल के रूप में सहेजा गया है, और CSV में एक्सटेंशन बदल गया है, तो कोई बोली काम नहीं करने वाली है। मुझे लगता है कि इस मामले में आपका एकमात्र विकल्प सीएसवी के रूप में प्रतियां बचाने के लिए एक्सेल का उपयोग करना होगा।
थॉमस के

जवाबों:


104

जैसा कि @ एस.लॉट कहते हैं, आपको अपनी फाइलें 'आरबी' मोड में खोलनी चाहिए, न कि 'आरयू' मोड में। हालाँकि यह आपकी वर्तमान समस्या का कारण नहीं हो सकता है। जहां तक ​​मुझे पता है, 'आरयू' मोड का उपयोग करने से आपको गड़बड़ होगी यदि \rडेटा में एम्बेडेड हैं , लेकिन किसी अन्य नाटक का कारण नहीं है। मैं यह भी नोट करता हूं कि आपके पास कई फाइलें हैं (सभी 'rU' के साथ खोली गई हैं?) लेकिन केवल एक समस्या पैदा कर रही है।

यदि csv मॉड्यूल कहता है कि आपके पास एक "NULL" (मूर्खतापूर्ण संदेश, आपकी फाइल में "NUL") बाइट होना चाहिए, तो आपको यह जांचने की आवश्यकता है कि आपकी फ़ाइल में क्या है। मेरा सुझाव है कि आप ऐसा करते हैं, भले ही 'आरबी' का उपयोग करने से समस्या दूर हो जाए।

repr()आपके डिबगिंग मित्र हैं (या बनना चाहते हैं)। यह एक प्लेटफ़ॉर्म इंडिपेंडेंट फ़ैशन में, जो आपको मिला है, उसे स्पष्ट रूप से दिखाएगा (जो मददगार है जो इस बात से अनजान है कि क्या odहै या क्या करता है)। यह करो:

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

और ध्यान से कॉपी (पेस्ट) न करें, परिणाम आपके प्रश्न के संपादन में (टिप्पणी में नहीं)।

यह भी ध्यान दें कि यदि फाइल वास्तव में डोडी है जैसे फ़ाइल के शुरू होने से उचित दूरी के भीतर no \ 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आउटपुट में) देख सकते हैं , तो आपके पास निश्चित रूप से फाइल में एनयूएल बाइट (एस) है, और आपको ऐसा कुछ करने की आवश्यकता होगी:

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

वैसे, क्या आपने पाठ संपादक के साथ फ़ाइल (अंतिम कुछ पंक्तियों सहित) को देखा है? क्या यह वास्तव में अन्य (कोई "NULL बाइट" अपवाद) फ़ाइलों की तरह एक उचित CSV फ़ाइल जैसा दिखता है?


इस बहुत विस्तृत मदद के लिए बहुत बहुत धन्यवाद। फ़ाइल में बहुत सारे \ x00 अक्षर हैं (प्रश्न को संपादित करें देखें) - यह अजीब है, क्योंकि एक पाठ संपादक में यह पूरी तरह से उचित CSV फ़ाइल की तरह दिखता है।
AP257

1
@ AP257: '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1OLE2 कम्पाउंड डॉक्यूमेंट फाइल को दर्शाते हुए "सिग्नेचर" है - उदाहरण के लिए एक्सेल 97-2003 .XLS फाइल । मुझे लगता है "एक पाठ संपादक में यह पूरी तरह से उचित CSV फ़ाइल जैसा दिखता है" पूरी तरह से अविश्वसनीय होने के लिए । आप एक अलग फ़ाइल, एक मान्य CSV फ़ाइल, किसी अन्य फ़ोल्डर या किसी अन्य मशीन या किसी अन्य समय पर देख रहे होंगे। ध्यान दें कि आपका odआउटपुट XLS फ़ाइल से नहीं था।
जॉन माकिन

8
@ AP257: कोई विशेष कारण जो आपने इस उत्तर को स्वीकार नहीं किया है?
जॉन मैकिन

काम करता है, लेकिन CSV को फ़िल्टर करने वाली फ़ाइल जैसी ऑब्जेक्ट के साथ संभव और अच्छा ऑन-द-फ्लाई होना चाहिए और इसे csv.readerसीधे पास किया जा सकता है ।
गेरिट

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=",")

यह मेरे लिए काम करता है।


मेरे मामले के लिए हल किया गया, अशक्त '\ 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

जहाँ स्थान आपके सीएसवी फ़ाइल की निर्देशिका है।


13

मैं इस समस्या से भी टकराया। पायथन csvमॉड्यूल का उपयोग करते हुए , मैं एमएस एक्सेल में बनाई गई एक एक्सएलएस फ़ाइल को पढ़ने की कोशिश कर रहा था और NULL byteआपको जो त्रुटि मिल रही थी, उसमें चल रहा था। मैंने चारों ओर देखा और पाया एमएस एक्सेल स्प्रेडशीट फ़ाइलों से डेटा को पढ़ने और स्वरूपण के लिए xlrd पायथन मॉड्यूल । xlrdमॉड्यूल के साथ , मैं न केवल फ़ाइल को ठीक से पढ़ पा रहा हूं, बल्कि मैं फ़ाइल के कई अलग-अलग हिस्सों तक भी पहुंच सकता हूं, जिस तरह से मैं पहले नहीं कर सका था।

मैंने सोचा कि यह आपकी मदद कर सकता है।


7
उस मॉड्यूल को इंगित करने के लिए धन्यवाद। दिलचस्प रूप से पर्याप्त है, मैं इसे डाउनलोड करने के लिए गया और देखा कि लेखक कोई और नहीं @John_Machin था जो इस सवाल पर शीर्ष टिप्पणी भी है।
इवान

11

UTF-16 से UTF-8 में स्रोत फ़ाइल के एन्कोडिंग को बदलने से मेरी समस्या हल हो जाती है।

पायथन में 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

आप एक जनरेटर को शून्य मानों को फ़िल्टर करने के लिए इनलाइन कर सकते हैं यदि आप बहाना चाहते हैं कि वे मौजूद नहीं हैं। बेशक यह मान रहा है कि अशक्त बाइट्स वास्तव में एन्कोडिंग का हिस्सा नहीं हैं और वास्तव में किसी प्रकार की गलत कलाकृतियों या बग हैं।

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 )

मोड को पढ़ने के लिए "आरबी" होना चाहिए।

http://docs.python.org/library/csv.html#csv.reader

यदि csvfile एक फ़ाइल ऑब्जेक्ट है, तो इसे उन प्लेटफ़ॉर्म पर 'b' फ़्लैग के साथ खोला जाना चाहिए जहाँ इससे फ़र्क पड़ता है।


@ AP257: "मदद नहीं करता है"? क्या मतलब? कोई विशिष्ट त्रुटि संदेश?
S.Lott

1
@ एस.लॉट: इसका मतलब है कि उसे पहले जैसा ही जवाब मिलता है। वास्तविकता यह है कि वह एक गिरगिट या आकार-प्रकार की फ़ाइल के साथ काम odकर रहा है ... जब वह इसे एक पाठ संपादक में देखता है या इसे देखता है, तो यह पूरी तरह से सामान्य CSV फ़ाइल की तरह दिखता है। हालाँकि जब वह पायथन रीप्र () के साथ पहले कुछ बाइट्स को डंप करता है, तो यह एक एक्सेल .XLS फ़ाइल की तरह बनता है (जिसका नाम बदलकर CSV एक्सटेंशन रखा गया है)।
जॉन मैकिन

@ जॉन मैकिन: "एक एक्सेल .XLS फ़ाइल (जिसका नाम बदलकर CSV एक्सटेंशन रखा गया है" समझ में आता है कि इसे बिल्कुल भी संसाधित नहीं किया जा सकता है।
S.Lott

1
@ S.Lott: उस सामग्री के साथ, यह समझ में आता है कि सीएसवी मॉड्यूल इसे संसाधित नहीं कर सकता है; हालाँकि xlrd मॉड्यूल इसे संसाधित कर सकता है। समझदारी से, न तो मॉड्यूल इनपुट फ़ाइल के नाम से कुछ भी प्रभावित करता है, अगर वास्तव में इनपुट एक नाम वाली फ़ाइल है।
जॉन माकिन

1
@ जॉन माचिन: ​​"न तो मॉड्यूल इनपुट फ़ाइल के नाम से कुछ भी प्रभावित करता है"। सच। मेरा आवेदन ढांचा इस तथ्य पर निर्भर करता है। हम किसी भी चीज़ के लिए फ़ाइलनाम पर भरोसा नहीं करते हैं, क्योंकि लोग गलती करते हैं ("झूठ")। इसलिए हमें एक क्लिक तक विकल्पों का एक गुच्छा देखना होगा।
S.Lott

2

appparently यह एक XLS फ़ाइल और के रूप में नहीं एक CSV फ़ाइल है http://www.garykessler.net/library/file_sigs.html पुष्टि


जरूरी नहीं, लेकिन हां, यह एक कारण हो सकता है। मुझे यह त्रुटि तब मिली जब मैंने एक CSV फ़ाइल को पार्स करने की कोशिश की जिसे एक्सेल ने XLSX फ़ाइल से बचाया था।
Cerin

इस मैजिक नंबर के साथ इसका कारण है XLSX का अलग मैजिक नंबर
जेवियर कॉम्बेल

2

सीएसवी रीडर के बजाय मैं स्ट्रिंग के लिए रीड फाइल और स्प्लिट फ़ंक्शन का उपयोग करता हूं:

lines = open(input_file,'rb') 

for line_all in lines:

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

1

मुझे भी यही त्रुटि मिली। फ़ाइल को UTF-8 में सहेजा गया और यह काम कर गई।


1
आपको एक ही त्रुटि संदेश मिल सकता है, लेकिन इसका कारण अलग होगा - आपने संभवतः इसे मूल रूप से UTF-16 (जिसे नोटपैड "यूनिकोड" कहा है) के रूप में सहेजा है।
जॉन मैकिन

1

यह मेरे साथ तब हुआ जब मैंने OpenOffice Calc के साथ एक CSV फ़ाइल बनाई। यह तब नहीं हुआ जब मैंने अपने टेक्स्ट एडिटर में CSV फ़ाइल बनाई, भले ही मैंने बाद में इसे Calc के साथ संपादित किया हो।

मैंने अपने टेक्स्ट एडिटर में कॉपी-पेस्ट करके मेरी कैलकस-निर्मित फ़ाइल से डेटा को एक नए एडिटर-निर्मित फ़ाइल में हल किया।


1

मुझे एक ही समस्या थी एक webservice से उत्पादित CSV को खोलने की, जो खाली हेडर में NULL बाइट्स डालती है। मैंने फ़ाइल को साफ़ करने के लिए निम्न कार्य किया:

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

उन सभी 'आरयू' फिल्ममॉडरों से नफरत के लिए: मैंने सिर्फ एक मैक पर विंडोज मशीन से एक सीएसवी फ़ाइल खोलने की कोशिश की, जिसमें 'आरबी' फिल्मकोड है और मुझे यह त्रुटि सीएसवी मॉड्यूल से मिली:

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

फ़ाइल को 'आरयू' मोड में खोलना ठीक काम करता है। मुझे यूनिवर्सल-न्यूलाइन मोड पसंद है - यह मुझे इतनी परेशानी से बचाता है।


0

मुझे इसका सामना तब करना पड़ा, जब किसी सही मिडलवेयर के बिना एक रिप्ड सीएसवीफाइल को स्क्रेपी का उपयोग करते हुए और रिस्पांड बॉडी को सीएसवीडर को सौंपने से पहले अनजिप कर दिया। इसलिए फ़ाइल वास्तव में एक सीएसवी फ़ाइल नहीं थी और 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

मैंने इस चेक को कोड में जोड़कर अपनी समस्या हल कर ली।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.