पायथन कैसे एक बाइनरी फ़ाइल लिखने के लिए?


128

मेरे पास पूर्णांक के रूप में बाइट्स की एक सूची है, जो कुछ इस तरह है

[120, 3, 255, 0, 100]

मैं इस सूची को बाइनरी के रूप में फ़ाइल में कैसे लिख सकता हूं?

क्या यह काम करेगा?

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
newFile.write(newFileBytes)

60
आप पूछते हैं "क्या यह काम करेगा?"। या तुमने कोशिश की?
स्टीफन टीटी

1
होना चाहिए TypeError: argument 1 must be string or buffer, not list
अनातोली टेकटोनिक

जवाबों:


128

यह वास्तव में क्या bytearrayहै:

newFileByteArray = bytearray(newFileBytes)
newFile.write(newFileByteArray)

यदि आप Python 3.x का उपयोग कर रहे हैं, तो आप bytesइसके बजाय (और शायद चाहिए, क्योंकि यह आपके इरादे को बेहतर बताता है) का उपयोग कर सकता है। लेकिन पायथन 2.x में, यह काम नहीं करेगा, क्योंकि इसके bytesलिए सिर्फ एक उपनाम है str। हमेशा की तरह, इंटरएक्टिव इंटरप्रेटर के साथ दिखाना पाठ के साथ व्याख्या करने की तुलना में आसान है, इसलिए मुझे बस ऐसा करने दें।

अजगर 3.x:

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
b'{\x03\xff\x00d'

पायथन 2.x:

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
'[123, 3, 255, 0, 100]'

1
बिलिन प्रकार का अच्छा उपयोग। बस ध्यान दें कि 2.6 में बायट्रे को जोड़ा गया था, यदि आप विरासत प्रणालियों का समर्थन करना चाहते हैं, तो इसे टाला जाना चाहिए।
पर्किन्स

7
@ पर्किन्स: ज़रूर, और आपको जेनरेटर के भाव से बचना चाहिए, अगर आपको 2.3 पर काम करने की ज़रूरत है, तो दोनों से सावधान रहें str.encodeऔर struct.packअगर आपको 2.2 पर काम करने की ज़रूरत है। लेकिन 2.6 अब 5 साल के लिए बाहर हो गया है; सभी तीन उबंटू LTS अभी भी समर्थन में हैं, समर्थन में सभी तीन OS X संस्करण, CentOS / RHEL के पिछले प्रमुख संस्करण, इत्यादि, सभी इसमें निर्मित हैं। यदि आपको 2.5 या 2.1 या 1.6 या जो भी हो, का समर्थन करने की आवश्यकता है। पता है ...
abarnert

4
विंडोज पर पायथन 2 के साथ, मैंने पाया कि लेखन bytearrayअभी भी धर्मान्तरित \nहै \r\n, जिससे यह द्विआधारी डेटा के लिए असंतोषजनक है, अगर फ़ाइल खोलने पर "बी" ध्वज पारित नहीं होता है।
फ़ेरसम

6
@ फैर्सम: बेशक; 2.x में बाइनरी बनाम टेक्स्ट मोड का क्या मतलब है। इससे कोई फर्क नहीं पड़ता कि आपकी बाइट किस प्रकार से आती हैं। (3.x में, निश्चित रूप से, द्विआधारी बनाम पाठ मोड का मतलब है कि आप बाइट्स बनाम यूनिकोड लिखते हैं, और \r\nसुविधा पाठ के लिए सार्वभौमिक newlines विकल्पों का हिस्सा है।)
निरस्त

मुझे यकीन नहीं है कि बायटियर () फ़ाइल लेखन के लिए एक अच्छा विकल्प है। आपको प्रबंधनीय विखंडू के आकार को सीमित करने की आवश्यकता होगी। अन्यथा एक बार जब आपकी फ़ाइलें बहुत अधिक हो जाती हैं तो आप मेमोरी से बाहर चले जाएंगे।
mckenzm

31

struct.packपूर्णांक मानों को बाइनरी बाइट में बदलने के लिए उपयोग करें , फिर बाइट्स लिखें। उदाहरण के लिए

newFile.write(struct.pack('5B', *newFileBytes))

हालाँकि मैं बाइनरी फाइल को कभी .txtविस्तार नहीं दूंगा ।

इस पद्धति का लाभ यह है कि यह अन्य प्रकारों के लिए भी काम करता है, उदाहरण के लिए यदि कोई मान 255 से अधिक हो तो आप '5i'पूर्ण 32-बिट पूर्णांक प्राप्त करने के बजाय प्रारूप के लिए उपयोग कर सकते हैं।


.txt ठीक है अगर आपके पास यह जानने का कोई तरीका है कि आप जो डेटा लिख ​​रहे हैं वह प्रिंट करने योग्य एससीआई रेंज के अंदर आता है। हालाँकि, आप सही हैं कि मुझे इस मामले में लगता है, क्योंकि उदाहरण डेटा में गैर मुद्रण योग्य वर्ण शामिल हैं।
पर्किन्स

@Perkins मैंने यह अनुमान नहीं लगाया कि मान ASCII रेंज में 256 से भी कम होंगे। यहां तक ​​कि अगर वे हैं, तो .txt फाइलें उन लोगों के लिए आरक्षित होनी चाहिए जो मानव के लिए समझ में आते हैं जो कभी भी बाइनरी डेटा पर लागू नहीं होते हैं।
मार्क रैनसम

1
आप सही कह रहे हैं, अगर आप 255 से ऊपर के मानों के साथ डेटा लिखने जा रहे हैं, तो भी जाने का तरीका है।
पर्किन्स

1
@MarkRansom: खैर, यह निश्चित रूप से "मैं कुछ मनमाने लेकिन निश्चित आकार के पूर्णांक की एक सूची है, की सामान्य समस्या का एक अच्छा समाधान है, मैं उन्हें बाइनरी फ़ाइल कैसे लिख सकता हूं?" और मैं लोगों को उस सवाल के लिए खोज और यह एक खोजने ... देख सकते हैं
abarnert

1
स्ट्रक्चर। पैक बेहतर जवाब है; यह केवल एक उपोत्पाद बनाने की तुलना में कहीं अधिक लचीला है।
सेठ

12

पूर्णांकों <256 से बाइनरी में परिवर्तित करने के लिए, chrफ़ंक्शन का उपयोग करें । तो आप निम्न कार्य कर रहे हैं।

newFileBytes=[123,3,255,0,100]
newfile=open(path,'wb')
newfile.write((''.join(chr(i) for i in newFileBytes)).encode('charmap'))

1
आप का मतलब <128 होना चाहिए। जैसा कि python3 शिकायत करता है: UnicodeEncodeError: 'ascii' कोडक चरित्र '\ x89' को स्थिति में सांकेतिक शब्दों में बदलना नहीं कर सकता है 0: ordinal not in range (128)
elig

2
नहीं, मेरा मतलब है <256, लेकिन एन्कोडिंग charmapबजाय होना चाहिए ascii, और python2 के साथ-साथ python3 में काम करता है। asciiएन्कोडिंग केवल को Python2 में काम करता है।
पर्किन्स

9

पायथन 3.2+ के रूप में, आप to_bytesदेशी अंतरंग विधि का उपयोग करके भी इसे पूरा कर सकते हैं :

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
for byte in newFileBytes:
    newFile.write(byte.to_bytes(1, byteorder='big'))

यानी, to_bytesइस मामले में प्रत्येक एकल कॉल लंबाई 1 की एक स्ट्रिंग बनाता है, इसके पात्रों के साथ बड़े-एंडियन ऑर्डर (जो लंबाई -1 स्ट्रिंग्स के लिए तुच्छ है) में व्यवस्थित होता है, जो पूर्णांक मान का प्रतिनिधित्व करता है byte। आप अंतिम दो पंक्तियों को एक एकल में भी छोटा कर सकते हैं:

newFile.write(''.join([byte.to_bytes(1, byteorder='big') for byte in newFileBytes]))

8

आप पायथन 3 सिंटैक्स का उपयोग करके निम्नलिखित कोड उदाहरण का उपयोग कर सकते हैं:

from struct import pack
with open("foo.bin", "wb") as file:
  file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))

यहाँ शेल वन-लाइनर है:

python -c $'from struct import pack\nwith open("foo.bin", "wb") as file: file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))'

1

अचार का उपयोग करें, इस तरह: अचार आयात करें

आपका कोड इस तरह दिखेगा:

import pickle
mybytes = [120, 3, 255, 0, 100]
with open("bytesfile", "wb") as mypicklefile:
    pickle.dump(mybytes, mypicklefile)

डेटा वापस पढ़ने के लिए, अचार .लोड विधि का उपयोग करें


3
यह 5 बाइट्स लंबाई की एक बाइनरी फ़ाइल का उत्पादन नहीं करता है, जहां एकमात्र सामग्री 120, 3, 255, 0, 100 है। एक बंद प्रणाली में, यह स्वीकार्य हो सकता है।
परवस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.