ज़िप आर्काइव कैसा दिखता है और हम इसके बारे में क्या कर सकते हैं

आपका दिन शुभ हो, प्रिय हेब्र!

पिछले आधे साल में, मेरी पालतू परियोजनाओं की टेढ़ी-मेढ़ी राह ने मुझे ऐसे संकटों में डाल दिया है, जहाँ से बाहर निकलना अभी भी असंभव है। और यह सब हानिरहित रूप से शुरू हुआ - चित्रों के साथ एक साइट, लेकिन पूर्णतावाद की भावना, एक फ्रीबी की खोज, साथ ही साथ मेरी मानसिकता की कुछ विशेषताओं ने इसे बदल दिया, जैसा कि मूल रूप से योजना बनाई गई थी, एक वास्तविक लंबी यात्रा में छोटा चलना। ठीक है, ठीक है, जैसा कि एक क्रांतिकारी क्रांतिकारी कहता था: "सीखो, अध्ययन करो और फिर से अध्ययन करो", लेकिन मुझे, विली-निली, इस सलाह का पालन करना होगा।

ओह, कुछ हम मुख्य विषय से विचलित थे। मैं अब आपको लंबे भाषणों से बोर नहीं करूंगा, लेकिन मैं व्यापार में उतर जाऊंगा।

एक ज़िप संग्रह बनाएँ


सिद्धांत रूप में, मैं यहां विनिर्देश को फिर से नहीं लिखूंगा। कुल मिलाकर, यह संरचना का वर्णन करने के लिए कोई मतलब नहीं है, क्योंकि यह सब मेरे सामने किया गया था।

उन लोगों के लिए जो लिंक का पालन करने के लिए बहुत आलसी हैं, मैं बस संक्षेप में बताऊंगा कि किसी भी ज़िप संग्रह में क्या होना चाहिए:

  • फ़ाइल प्रविष्टि:
    • स्थानीय फ़ाइल हेडर
    • उपयोगी डेटा
    • डेटा डिस्क्रिप्टर (वैकल्पिक, तब उपयोग किया जाता है जब हम फ़ाइल का आकार और उसके हैश को तब तक नहीं जानते हैं जब तक कि हम इसे अंत तक नहीं पढ़ लेते)
  • केंद्रीय निर्देशिका फ़ाइल हैडर (प्रत्येक फ़ाइल के लिए। यह पुस्तक की सामग्री की तालिका की तरह है, जहां प्रत्येक अनुभाग और पृष्ठ जिस पर इसे प्राप्त किया जा सकता है)
  • केंद्रीय निर्देशिका का अंत

यह जानकर, हम एक सरल संग्रह लिखने की कोशिश कर सकते हैं जिसमें केवल दो फाइलें होंगी:

<?php //        (1.txt  2.txt)   : $entries = [ '1.txt' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc id ante ultrices, fermentum nibh eleifend, ullamcorper nunc. Sed dignissim ut odio et imperdiet. Nunc id felis et ligula viverra blandit a sit amet magna. Vestibulum facilisis venenatis enim sed bibendum. Duis maximus felis in suscipit bibendum. Mauris suscipit turpis eleifend nibh commodo imperdiet. Donec tincidunt porta interdum. Aenean interdum condimentum ligula, vitae ornare lorem auctor in. Suspendisse metus ipsum, porttitor et sapien id, fringilla aliquam nibh. Curabitur sem lacus, ultrices quis felis sed, blandit commodo metus. Duis tincidunt vel mauris at accumsan. Integer et ipsum fermentum leo viverra blandit.', '2.txt' => 'Mauris in purus sit amet ante tempor finibus nec sed justo. Integer ac nibh tempus, mollis sem vel, consequat diam. Pellentesque ut condimentum ex. Praesent finibus volutpat gravida. Vivamus eleifend neque sit amet diam scelerisque lacinia. Nunc imperdiet augue in suscipit lacinia. Curabitur orci diam, iaculis non ligula vitae, porta pellentesque est. Duis dolor erat, placerat a lacus eu, scelerisque egestas massa. Aliquam molestie pulvinar faucibus. Quisque consequat, dolor mattis lacinia pretium, eros eros tempor neque, volutpat consectetur elit elit non diam. In faucibus nulla justo, non dignissim erat maximus consectetur. Sed porttitor turpis nisl, elementum aliquam dui tincidunt nec. Nunc eu enim at nibh molestie porta ut ac erat. Sed tortor sem, mollis eget sodales vel, faucibus in dolor.', ]; //      Lorem.zip,      cwd (      ) $destination = 'Lorem.zip'; $handle = fopen($destination, 'w'); //      ,    ,     ,   "" Central Directory File Header $written = 0; $dictionary = []; foreach ($entries as $filename => $content) { //         Local File Header,     //        ,      . $fileInfo = [ //     'versionToExtract' => 10, //   0,        - 'generalPurposeBitFlag' => 0, //      ,    0 'compressionMethod' => 0, // -    mtime ,    ,      ? 'modificationTime' => 28021, //   , ? 'modificationDate' => 20072, //      .     ,       ,   ? 'crc32' => hexdec(hash('crc32b', $content)), //     .        . //       :) 'compressedSize' => $size = strlen($content), 'uncompressedSize' => $size, //    'filenameLength' => strlen($filename), //  .    ,   0. 'extraFieldLength' => 0, ]; //      . $LFH = pack('LSSSSSLLLSSa*', ...array_values([ 'signature' => 0x04034b50, //  Local File Header ] + $fileInfo + ['filename' => $filename])); //       ,       Central Directory File Header $dictionary[$filename] = [ 'signature' => 0x02014b50, //  Central Directory File Header 'versionMadeBy' => 798, //  .    ,  -  . ] + $fileInfo + [ 'fileCommentLength' => 0, //    . No comments 'diskNumber' => 0, //     0,        'internalFileAttributes' => 0, //    'externalFileAttributes' => 2176057344, //    'localFileHeaderOffset' => $written, //      Local File Header 'filename' => $filename, //  . ]; //      $written += fwrite($handle, $LFH); //    $written += fwrite($handle, $content); } // ,     ,    . //          End of central directory record (EOCD) $EOCD = [ //  EOCD 'signature' => 0x06054b50, //  .    ,   0 'diskNumber' => 0, //      -  0 'startDiskNumber' => 0, //       . 'numberCentralDirectoryRecord' => $records = count($dictionary), //    .    ,     'totalCentralDirectoryRecord' => $records, //   Central Directory Record. //      ,      'sizeOfCentralDirectory' => 0, // ,    Central Directory Records 'centralDirectoryOffset' => $written, //     'commentLength' => 0 ]; //     !   foreach ($dictionary as $entryInfo) { $CDFH = pack('LSSSSSSLLLSSSSSLLa*', ...array_values($entryInfo)); $written += fwrite($handle, $CDFH); } // ,   .  ,    $EOCD['sizeOfCentralDirectory'] = $written - $EOCD['centralDirectoryOffset']; //     End of central directory record $EOCD = pack('LSSSSLLS', ...array_values($EOCD)); $written += fwrite($handle, $EOCD); //  . fclose($handle); echo '  : ' . $written . ' ' . PHP_EOL; echo '     `unzip -tq ' . $destination . '`' . PHP_EOL; echo PHP_EOL; 

इस आदिम कोड को चलाने की कोशिश करें और आउटपुट आपको एक लोरेम.जिप फाइल देगा जिसमें 1.txt और 2.txt होगा।

और क्यों?


बेशक, कोई भी पर्याप्त व्यक्ति यह कहेगा कि php में अभिलेख लिखना एक निरर्थक उपक्रम है, विशेष रूप से जैसे कि ज़िप जैसे प्रारूप के लिए, हर स्वाद और रंग के लिए तैयार कार्यान्वयन का एक समूह है। और उसी php में रेडीमेड लाइब्रेरी हैं। मैं भी इतना ही कहूंगा :)

लेकिन, फिर, यह पूरा लेख क्यों है, मैंने इसे लिखने में समय क्यों लगाया, और आप इसे पढ़ रहे हैं?
और फिर, कि सब कुछ इतना सरल नहीं है और यह जानना कि ज़िप कैसे काम करता है, हमारे लिए कुछ अतिरिक्त संभावनाएं खोलता है।

सबसे पहले, मुझे उम्मीद है, कम से कम थोड़ा, लेकिन यह उन लोगों की मदद करेगा जो ज़िप की संरचना को समझना चाहते हैं।
और दूसरी बात, अपने स्वयं के हाथों से संग्रह का निर्माण करना, हमारे पास नियंत्रण है, और, सबसे महत्वपूर्ण बात, इसके आंतरिक डेटा तक पहुंच।

हम स्थानीय फ़ाइल हैडर और सेंट्रल डायरेक्टरी फ़ाइल हैडर की पूर्व-गणना कर सकते हैं, और फिर ऑन-डिमांड किसी भी सामग्री और फाइलों के आदेश के साथ मक्खी पर एक ज़िप संग्रह तैयार करते हैं, बस इस डेटा को प्रतिस्थापित करते हैं। और I / O को छोड़कर कोई ओवरहेड नहीं है।

या, हम संग्रह को रिकॉर्ड कर सकते हैं, उदाहरण के लिए, इसे क्लाउड पर अपलोड कर सकते हैं, जो खंडित डाउनलोड का समर्थन करता है और, प्रत्येक फ़ाइलों के लिए ऑफ़सेट जानते हुए, किसी भी संग्रह फ़ाइल को प्राप्त करता है, जैसे कि यह संग्रह में बिल्कुल नहीं था, केवल एक जोड़ना अनुरोध के लिए शीर्षक। और फिर यह सब अनुमानित किया जा सकता है और ...

ठीक है, चलो खुद से आगे नहीं। यदि आप इस विषय में रुचि रखते हैं, तो निम्नलिखित लेखों में मैं इन अवसरों पर विचार करने और उन्हें उपयोग करने का तरीका दिखाने की कोशिश करूंगा।


'diskNumber' => 0, // मैं आमतौर पर हर जगह 0 भर में आया, और विशेष रूप से मैंने फैसला किया कि मैं इसमें कमी नहीं करूंगा
जैसा कि बेरेज़ ने सुझाव दिया था, बहु-वॉल्यूम संग्रह में वॉल्यूम संख्या।

Source: https://habr.com/ru/post/hi471066/


All Articles