2012-05-21 10 views
10

मुझे पता है कि बाइट्स को कैसे पढ़ा जाए - x.read(number_of_bytes), लेकिन मैं पायथन में बिट्स कैसे पढ़ सकता हूं?किसी फ़ाइल से बिट्स को कैसे पढ़ा जाए?

मैं एक बाइनरी फ़ाइल

कोई भी विचार या दृष्टिकोण से केवल 5 बिट्स (नहीं 8 बिट [1 बाइट]) को पढ़ने के लिए है?

+1

उन बिट्स लगातार कर रहे हैं? यदि हां, तो बाइट में पांच सबसे महत्वपूर्ण बिट्स, या पांच कम से कम महत्वपूर्ण बिट्स? –

उत्तर

21

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

b = x.read(1) 
firstfivebits = b >> 3 

या अगर आप 5 से कम महत्वपूर्ण बिट के बजाय 5 सबसे महत्वपूर्ण बिट चाहता था:

b = x.read(1) 
lastfivebits = b & 0b11111 

कुछ अन्य उपयोगी बिट हेरफेर की जानकारी यहां पाया जा सकता: http://wiki.python.org/moin/BitManipulation

+1

जब मेरी प्रतिष्ठा 15 हो जाती है, तो मैं आपको अंगूठे दूंगा! (मैं यहां नया हूं) इसलिए, यदि मैं ऐसा करता हूं: बी = x.read (1) फर्स्टफिवबिट्स = बी >> 3 मुझे पहले 5 बिट मिलेंगे ... क्यों नहीं firstfivebits = b >> 5? वाई मतलब ... क्यों बी >> 3? –

+7

@ ह्यूगोमेडिना यदि आपको नहीं पता कि क्यों 'firstfivebits = b >> 3' आपको यकीन है कि आपको बिट्स के साथ फिडलिन होना चाहिए? (आप अंधे या कुछ जा सकते हैं;)। –

+1

अब मुझे यह मिलता है, क्योंकि 1 बाइट = 8 बिट्स हम दाएं-शिफ्ट ऑपरेटर 3 (जैसे उन 3 कम महत्वपूर्ण बिट्स को हटाने की तरह) लागू करेंगे ताकि हम बाइट में शेष 5 बिट प्राप्त कर सकें –

2

के रूप में स्वीकार्य उत्तर राज्य, मानक पायथन I/O केवल एक बार में पूरे बाइट को पढ़ और लिख सकता है। हालांकि आप Bitwise I/O के लिए इस नुस्खा का उपयोग करके बिट्स की ऐसी धारा का अनुकरण कर सकते हैं।

अद्यतन:

के बाद से Rosetta कोड वेबसाइट के GNU license शब्दशः नकल, यहाँ बिट धारा मैं/अपनी संपूर्णता में हे की पायथन संस्करण है की अनुमति देता है:

अद्यतन 2:

रोसेट कोड के पायथन संस्करण को पाइथन 2 & 3 में अपरिवर्तित में काम करने के बाद, मैंने इस जवाब में परिवर्तनों को शामिल किया है।

class BitWriter(object): 
    def __init__(self, f): 
     self.accumulator = 0 
     self.bcount = 0 
     self.out = f 

    def __del__(self): 
     try: 
      self.flush() 
     except ValueError: # I/O operation on closed file 
      pass 

    def _writebit(self, bit): 
     if self.bcount == 8: 
      self.flush() 
     if bit > 0: 
      self.accumulator |= 1 << 7-self.bcount 
     self.bcount += 1 

    def writebits(self, bits, n): 
     while n > 0: 
      self._writebit(bits & 1 << n-1) 
      n -= 1 

    def flush(self): 
     self.out.write(bytearray([self.accumulator])) 
     self.accumulator = 0 
     self.bcount = 0 


class BitReader(object): 
    def __init__(self, f): 
     self.input = f 
     self.accumulator = 0 
     self.bcount = 0 
     self.read = 0 

    def _readbit(self): 
     if not self.bcount: 
      a = self.input.read(1) 
      if a: 
       self.accumulator = ord(a) 
      self.bcount = 8 
      self.read = len(a) 
     rv = (self.accumulator & (1 << self.bcount-1)) >> self.bcount-1 
     self.bcount -= 1 
     return rv 

    def readbits(self, n): 
     v = 0 
     while n > 0: 
      v = (v << 1) | self._readbit() 
      n -= 1 
     return v 

if __name__ == '__main__': 
    import os 
    import sys 
    # determine module name from this file's name and import it 
    module_name = os.path.splitext(os.path.basename(__file__))[0] 
    bitio = __import__(module_name) 

    with open('bitio_test.dat', 'wb') as outfile: 
     writer = bitio.BitWriter(outfile) 
     chars = '12345abcde' 
     for ch in chars: 
      writer.writebits(ord(ch), 7) 

    with open('bitio_test.dat', 'rb') as infile: 
     reader = bitio.BitReader(infile) 
     chars = [] 
     while True: 
      x = reader.readbits(7) 
      if reader.read == 0: 
       break 
      chars.append(chr(x)) 
     print(''.join(chars)) 

एक और उपयोग के उदाहरण दिखा कैसे एक 8 बिट बाइट ASCII धारा को त्यागकर सबसे महत्वपूर्ण "अप्रयुक्त" सा ... और इसे वापस पढ़ें "संकट" के लिए।

import sys 
import bitio 

o = bitio.BitWriter(sys.stdout) 
c = sys.stdin.read(1) 
while len(c) > 0: 
    o.writebits(ord(c), 7) 
    c = sys.stdin.read(1) 

... और "decrunch" एक ही धारा में:

import sys 
import bitio 

r = bitio.BitReader(sys.stdin) 
while True: 
    x = r.readbits(7) 
    if not r.read: # nothing read 
     break 
    sys.stdout.write(chr(x)) 
संबंधित मुद्दे