2009-11-09 10 views
9

में एक .gz फ़ाइल का असंपीड़ित आकार जाओ gzip का प्रयोग, बता() रिटर्न असम्पीडित फ़ाइल में ऑफसेट।
प्रगति पट्टी दिखाने के लिए, मैं फ़ाइल के मूल (असम्पीडित) आकार को जानना चाहता हूं।
क्या पता लगाने का कोई आसान तरीका है?अजगर

उत्तर

11

gzip format एक क्षेत्र ISIZE कहा जाता है यह बताता है कि:

This contains the size of the original (uncompressed) input data modulo 2^32.

01,235,164:

gzip.py में, जो मुझे लगता है आप gzip समर्थन के लिए क्या उपयोग कर रहे है, वहाँ एक विधि _read_eof कहा जाता है इस तरह के रूप में परिभाषित किया है

def _read_eof(self): 
    # We've read to the end of the file, so we have to rewind in order 
    # to reread the 8 bytes containing the CRC and the file size. 
    # We check the that the computed CRC and size of the 
    # uncompressed data matches the stored values. Note that the size 
    # stored is the true file size mod 2**32. 
    self.fileobj.seek(-8, 1) 
    crc32 = read32(self.fileobj) 
    isize = U32(read32(self.fileobj)) # may exceed 2GB 
    if U32(crc32) != U32(self.crc): 
     raise IOError, "CRC check failed" 
    elif isize != LOWU32(self.size): 
     raise IOError, "Incorrect length of data produced" 

वहां आप देख सकते हैं कि ISIZE फ़ील्ड पढ़ा जा रहा है, लेकिन केवल त्रुटि पहचान के लिए इसे self.size पर तुलना करने के लिए। इसका मतलब यह होना चाहिए कि GzipFile.size वास्तविक असम्पीडित आकार को संग्रहीत करता है। हालांकि, मैं सोचता हूं यह सार्वजनिक रूप से खुलासा नहीं है, इसलिए आपको इसे बेनकाब करने के लिए इसे हैक करना पड़ सकता है। इतना यकीन नहीं, क्षमा करें।

मैंने अभी यह सब देखा है, और मैंने कोशिश नहीं की है इसलिए मैं गलत हो सकता था। मुझे उम्मीद है कि यह आपके लिए कुछ उपयोग है। क्षमा करें अगर मैंने आपके प्रश्न को गलत समझा।

+0

मुझे लगता है कि यह काफी अच्छा है। 4 जी से बड़ी फ़ाइल के मामले में, फ़ाइल आकार को 4 जी + आईएसआईजेई में सेट करने के लिए प्रगति पट्टी में कुछ हेरिस्टिक्स जोड़ना आसान है, अगर बताएं() इंगित करता है कि हम आईएसआईजेई के बहुत करीब हैं। –

+0

मुझे एक ही चीज़ करने की ज़रूरत है और मैं फ़ाइल आकार देने के लिए GzipFile क्लास को विस्तारित करने का प्रयास कर रहा हूं, लेकिन मैं असफल हूं, आप इसे कैसे काम करते हैं? – lanrat

+0

अद्यतन: यह फ़ंक्शंस मेरे लिए काम करता है: http://code.activestate.com/lists/python-list/245777/ – lanrat

4

यूनिक्स रास्ता: का उपयोग करें "gunzip -l file.gz" subprocess.call/os.popen, कब्जा के माध्यम से और इसके उत्पादन को पार्स।

+0

मेरे से पुराने ऑपरेटिंग सिस्टम को कभी भी स्पर्श न करें ... गंभीरता से बोलते हुए: मैं एक पाइथन समाधान की तलाश में हूं, क्योंकि कोड सभी प्लेटफ़ॉर्म के लिए है। –

+2

विंडोज कम से कम 24 या 25 वर्ष का है। संस्करण 1 1 9 85 के आसपास या बाहर आया। आप की उम्र क्या है? – jmucchiello

+0

44.5 (और आखिरी बार 18 पर यूनिक्स का इस्तेमाल किया गया) –

0

gzip मॉड्यूल के लिए स्रोत को देखते हुए, मुझे लगता है कि GzipFile के लिए अंतर्निहित फ़ाइल ऑब्जेक्ट fileobj प्रतीत होता है। तो:

mygzipfile = gzip.GzipFile() 
... 
mygzipfile.fileobj.tell() 

?

शायद ऐसा करने से पहले कुछ सैनिटी जांच करना अच्छा होगा, यह जांचना कि यह विशेषता hasattr के साथ मौजूद है।

नहीं वास्तव में एक सार्वजनिक एपीआई, लेकिन ...

+0

.tell() बहुत अच्छा काम करता है। जो मैं खोज रहा हूं वह मूल फ़ाइल आकार है। –

+0

mygzipfile.tell नहीं), इसके बजाय mygzipfile.fileobj.tell()। –

4

पिछले 4 बाइट्स फ़ाइल के मूल आकार पकड़ .gz

+3

अंतिम 4 बाइट्स "मूल (असंपीड़ित) इनपुट डेटा मॉड्यूल 2^32 का आकार है।" (Http://www.gzip.org/zlib/rfc-gzip.html) – Gumbo

0

GzipFile.size असम्पीडित आकार को संग्रहीत करता है, लेकिन जब आप फ़ाइल पढ़ते हैं तो यह केवल बढ़ता जाता है, इसलिए आपको गैर-सार्वजनिक GzipFile.size के बजाय लेन (fd.read()) पसंद करना चाहिए।

+0

क्या होगा यदि फ़ाइल बहुत बड़ी है? – allyourcode

+0

@allyourcode: लंबे समय तक प्रतीक्षा करें :) – quetzalcoatl

1
f = gzip.open(filename) 
    # kludge - report uncompressed file position so progess bars 
    # don't go to 400% 
    f.tell = f.fileobj.tell 
12

असम्पीडित आकार gzip फ़ाइल का अंतिम 4 बाइट में संग्रहित है। हम बाइनरी डेटा पढ़ सकते हैं और इसे एक int में परिवर्तित कर सकते हैं। (यह केवल 4GB के तहत फ़ाइलों के लिए काम करेंगे)

import struct 

def getuncompressedsize(filename): 
    with open(filename, 'rb') as f: 
     f.seek(-4, 2) 
     return struct.unpack('I', f.read(4))[0] 
+0

त्रुटि से बचने के लिए फ़ाइल '' आरबी '' खोलें: अनपैक की लंबाई 4 की स्ट्रिंग तर्क की आवश्यकता है। – slv

+0

यह वही है जो पुराने ** जॉर्ज इज़राइल पेना ** के उत्तर में दिखाया गया है, इसलिए जब आपका उत्तर एक आसान काम प्रदान करता है, तो यह विषय में ज्यादा कुछ नहीं जोड़ता है। इसके अलावा, जैसा कि टिप्पणियां पुराने उत्तर में कहती हैं, केवल अंतिम 4 बाइट्स के आधार पर वास्तव में 100% मूर्खतापूर्ण नहीं है, क्योंकि जीजेड आपको फ़ाइल – quetzalcoatl

1

मैं प्रदर्शन के बारे में निश्चित नहीं हूँ, लेकिन इस का उपयोग करके gzip जादू जानने के बिना प्राप्त किया जा सकता:

with gzip.open(filepath, 'rb') as file_obj: 
    file_size = file_obj.seek(0, io.SEEK_END) 

यह भी अन्य के लिए काम करना चाहिए (संकुचित) धारा पाठकों जैसे bz2 या सादा open

संपादित करें: टिप्पणियों में सुझाए गए अनुसार, 2 दूसरी पंक्ति में io.SEEK_END द्वारा प्रतिस्थापित किया गया था, जो निश्चित रूप से अधिक पठनीय और शायद भविष्य के सबूत हैं।

+0

यानी 'file_size = file_obj.seek (0, io) के अंत में नए ब्लॉक जोड़ने की अनुमति देता है। SEEK_END) ' – user3780389