पायथन में बाइनरी फ़ाइल से पूर्णांक पढ़ना


83

मैं पायथन में बीएमपी फ़ाइल पढ़ने की कोशिश कर रहा हूं । मुझे पता है कि पहले दो बाइट बीएमपी फर्म को दर्शाते हैं। अगले 4 बाइट्स फ़ाइल का आकार हैं। जब मैं निष्पादित करता हूं:

fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size = int(fin.read(4))  

मुझे मिला:

ValueError: आधार के लिए अमान्य शाब्दिक () आधार 10 के साथ: 'F # \ x13'

मैं जो करना चाहता हूं, उन चार बाइट्स को एक पूर्णांक के रूप में पढ़ रहा हूं, लेकिन ऐसा लगता है कि पायथन उन्हें पात्रों के रूप में पढ़ रहा है और एक स्ट्रिंग लौटा रहा है, जिसे एक पूर्णांक में परिवर्तित नहीं किया जा सकता है। मैं इसे सही तरीके से कैसे कर सकता हूं?


2
यदि आपका लक्ष्य अपनी खुद की बीएमपी लाइब्रेरी लिखने में समय बिताने के बजाय बिटमैप का उपयोग करना है (ऐसा नहीं है जो ध्वनि की तरह नहीं है ...) आप पीआईएल pythonware.com/products/pil का उपयोग कर सकते हैं जिसे आपने पहले ही स्थापित किया है। प्रयास करें: आयात छवि
जारेड अपडेटेड

7
धन्यवाद jared, लेकिन मैं केवल मज़े करने के लिए bmp को पढ़ना चाहता था! :)
मैनुअल आराज़ जूल 22'09

जवाबों:


123

readविधि स्ट्रिंग के रूप बाइट्स की एक दृश्य देता है। एक स्ट्रिंग बाइट-क्रम से बाइनरी डेटा में परिवर्तित करने के लिए, अंतर्निहित structमॉड्यूल का उपयोग करें : http://docs.python.org/library/struct.html

import struct

print(struct.unpack('i', fin.read(4)))

ध्यान दें कि unpackहमेशा एक टपल लौटता है, इसलिए struct.unpack('i', fin.read(4))[0]पूर्णांक मान देता है जो आप बाद में हैं।

आपको शायद प्रारूप स्ट्रिंग का उपयोग करना चाहिए '<i'(<एक संशोधक है जो कि छोटे-एंडियन बाइट-ऑर्डर और मानक आकार और संरेखण को इंगित करता है - डिफ़ॉल्ट प्लेटफ़ॉर्म के बाइट ऑर्डर, आकार और संरेखण का उपयोग करने के लिए है)। बीएमपी प्रारूप युक्ति के अनुसार, बाइट्स को इंटेल / लिटिल-एंडियन बाइट ऑर्डर में लिखा जाना चाहिए।


22
लिखने के बजाय i = struct.unpack(...)[0]मैं अक्सर लिखता हूंi, = struct.unpack(...)
ओटो ऑलमेन्डर

@Otto क्या कोई कारण है कि आप दूसरे पर एक तरह से पसंद करते हैं? क्या कोई तार्किक अंतर है?
कालस्टर

2
मुझे यह बहुत आश्चर्यजनक लगता है कि पायथन में एक फ़ाइल से पूर्णांक (या शॉर्ट्स आदि) पढ़ने के लिए एक अंतर्निहित फ़ंक्शन नहीं है। मैं कोई जावा विशेषज्ञ नहीं हूं, लेकिन मेरा मानना ​​है कि ऐसा करने के लिए इसमें रीडयून्सगॉटशॉर्ट () जैसे मूल कार्य हैं।
कैल्टर

@codeape क्या आप परिभाषित कर सकते हैं कि [0] कृपया कर रहा है या कम से कम यह किस प्रकार का भाषा तत्व है। यह तुरंत स्पष्ट नहीं है और पायथन प्रलेखन के लिए खोज करना लगभग असंभव है।
कैल्टर

सूचियों और टुपल्स के लिए, obj [N] का अर्थ है: obj का Nth तत्व प्राप्त करें। Docs.python.org/tutorial/introduction.html#lists
कोडेक्ट

50

एक वैकल्पिक विधि जो 'struct.unpack ()' का उपयोग नहीं करती है वह NumPy का उपयोग करेगा :

import numpy as np

f = open("file.bin", "r")
a = np.fromfile(f, dtype=np.uint32)

'dtype' डेटाटाइप का प्रतिनिधित्व करता है और यह int #, uint #, float #, complex # या उपयोगकर्ता परिभाषित प्रकार हो सकता है। देखते हैं numpy.fromfile

व्यक्तिगत रूप से सरणी / मैट्रिक्स डेटा के साथ काम करने के लिए NumPy का उपयोग करना पसंद करते हैं क्योंकि यह पायथन सूचियों का उपयोग करने की तुलना में बहुत तेज है।


13
फ़ाइल खोलने को छोड़ दिया जा सकता है:a = np.fromfile('file.bin', dtype=np.uint32)
मैथ्यू शॉफर

17

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

file_size = int.from_bytes(fin.read(2), byteorder='big')

ध्यान दें कि इस फ़ंक्शन को यह निर्दिष्ट करने की आवश्यकता है कि क्या संख्या बड़े या छोटे-एंडियन प्रारूप में एन्कोडेड है, इसलिए आपको यह सुनिश्चित करने के लिए एंडियन-नेस निर्धारित करना होगा कि यह सही ढंग से काम करता है।


6

सिवाय structआप arrayमॉड्यूल का उपयोग भी कर सकते हैं

import array
values = array.array('l') # array of long integers
values.read(fin, 1) # read 1 integer
file_size  = values[0]

अच्छी बात। लेकिन यह समाधान संरचना मॉड्यूल की तरह लचीला नहीं है, क्योंकि सभी तत्व मानों के माध्यम से पढ़ते हैं। () लंबे पूर्णांक होना चाहिए (यह एक लंबे पूर्णांक, एक बाइट और फिर एक लंबे पूर्णांक को पढ़ने के लिए सुविधाजनक नहीं है, पूर्णांक के साथ) सरणी मॉड्यूल)।
एरिक ओ लेबिगॉट

मैं सहमत हूँ। arrayबाइनरी फ़ाइल को पढ़ने का एक प्रभावी तरीका है लेकिन बहुत लचीला नहीं है जब हमें संरचना से निपटना पड़ता है, जैसा कि आपने सही उल्लेख किया है।
निक डंडौलकिस

1
array.read 1.51 के बाद array.fromfile के पक्ष में पदावनत कर दिया गया है

4

जैसा कि आप बाइनरी फ़ाइल पढ़ रहे हैं, आपको इसे पूर्णांक में अनपैक करने की आवश्यकता है, इसलिए इसके लिए स्ट्रक्चर मॉड्यूल का उपयोग करें

import struct
fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size, = struct.unpack("i",fin.read(4))

रिटर्न एक टपल struct.unpack
ल्यूक

1

जब आप एक बाइनरी फ़ाइल से पढ़ते हैं, तो बाइट्स नामक एक डेटा प्रकार का उपयोग किया जाता है। यह सूची या ट्यूपल की तरह एक सा है, सिवाय इसके कि यह केवल 0 से 255 तक पूर्णांक स्टोर कर सकता है।

प्रयत्न:

file_size = fin.read(4)
file_size0 = file_size[0]
file_size1 = file_size[1]
file_size2 = file_size[2]
file_size3 = file_size[3]

या:

file_size = list(fin.read(4))

के बजाय:

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