整體結構

整體結構

我有4個問題:

  1. 是否可以掃描整個 zip 檔案並在其中導航,而無需使用 PHP 提取整個 zip?
  2. 時間效率會高嗎?即我有一個大約 50GB 的 zip 文件,其中包含許多小文件(尤其是過去的許多圖像),我想使用 PHP 製作一個文件瀏覽器。
  3. 這可以遞歸地完成嗎,即如果我在一個大拉鍊中有很多拉鍊,我能夠解析它們嗎?
  4. 如果我可以解析 zip,這是否意味著我可以像在普通文件瀏覽器中一樣打開其中的文件?

答案1

大概。簡單的谷歌搜尋就出現了。看起來完全支援 Zip 檔案。

答案2

全部同意。至少如果“掃描整個 zip 檔案”並不意味著實際掃描整個文件。如果它很小,那沒關係,但如果它很大,那就沒關係。

簡而言之,ZIP 檔案的建構方式使得無需讀取整個檔案即可列出、更新、刪除、新增檔案。另請注意,最初 ZIP 通常用於保存可以跨越多個磁碟的磁碟。換句話說,您可以有一個從磁碟#1 開始到磁碟#44 結束的zip 檔案。

如果檔案位於一個磁碟上,則不需要磁碟#1 - 磁碟#28 來提取磁碟#29 上的檔案 342 這一事實也適用,但從概念上講,它可能更容易理解。您不會讀取 file#1 到 file#341 來提取 file#342。

除此之外,簡而言之,ZIP 檔案以中央目錄結束。該目錄保存有關 zip 存檔當前狀態的資訊以及應該使用的資訊。


整體結構

zip 檔案的整體結構通常是(簡化的):

Local File Header 1
      File Data   1
      Descriptor  1 (optional) 
Local File Header 2
      File Data   2
      Descriptor  2 (optional)
Local File Header N
      File Data   N
      Descriptor  N (optional)

Central Directory
   Details File 1
   Details File 2
   Details File N
   End Of Central Directory

但是 ZIP 檔案“允許”對於非存檔資料以及刪除和新增條目(不需要刪除資料)。

這裡允許使用相當靈活

所以存檔可能是這樣的:

Local File Header 1
      File Data   1
Local File Header 2
      File Data   2
Non Archive Data    << not part of the archive, but part of the file.
Local File Header 3
      File Data   3
      Descriptor  3
Non Archive Data    << not part of the archive, but part of the file.
Central Directory   << old central directory
   Details File 1
   Details File 2
   End Of Central Directory

Local File Header 4
      File Data   4

Central Directory
   Details File 1
   Details File 3
   Details File 4
   End Of Central Directory

這裡有一種情況,其中一些記錄之間添加了數據,文件 2 已被刪除,但數據未刪除,文件 4 已添加,並且寫入了新的中央目錄,但未刪除舊的。

事實上,我們可以將 zip 檔案附加到任何現有文件中,並且它仍然可用。

foo.zip
[GIF IMAGE]
[ZIP FILE RECORD]
[LETTER TO MOM]
[ZIP FILE RECORD]
[CENTRAL DIRECTORY]

人們可能會稱該檔案一團糟,但作為 ZIP 存檔,它仍然可讀。人們可以爭辯說它根據規範無效,並願意忽略它,但那是另一回事了。

重點是:

正確的 ZIP 閱讀器使用最後一個中央目錄。該文件應始終保存有關存檔當前狀態的資訊。它提供有關檔案名稱、時間、日期、壓縮方法、磁碟開始、磁碟結束、檔案數量、每個檔案開始和結束位置、每個檔案的校驗和等資訊。

人們可以將 zip 檔案視為一大堆數據,CD 上標示了每個檔案的開始和結束位置 ++。


一般來說

大多數 zip 檔案當然比這個乾淨得多,但只是提供一些背景資訊。

簡而言之:要獲得存檔中文件的概覽,只需閱讀 CD。例如可以透過這個列出:

file1 date size_compressed size_uncompressed
file2 date size_compressed size_uncompressed
file3 date size_compressed size_uncompressed
file4 date size_compressed size_uncompressed

本機檔案頭在恢復損壞的檔案或 CD 遺失等情況下很有用,但也可能缺少。它通常保存檔案資料的大小,但並非總是如此。如果沒有,通常是

Local File Header
  ...
  size_compressed: 0
  size_uncompressed: 0
  ...
File Data
Descriptor
   size_compressed: 3214
   size_uncompressed: 6128

因此,如果您從位元組 0 讀取文件,您最終會遇到必須猜測讀取資料開始和結束位置的問題。

一個典型的原因是 ZIP 可以歸檔資料流。因此,在寫入文件之前,人們不知道文件的大小,也不知道校驗和,因此標頭無法保存此資訊。另外請記住,一個檔案可以跨越多個磁碟。但是,應該始終將大小添加到 CD 中。


由於人們可以讀取文件的開始和結束位置,因此也很容易挑選一個文件。如果 CD 說檔案從偏移量 632156 開始並以 952144 結束,則讀取這些位元組,如果已壓縮,則相應地解壓縮。

如果您有嵌套文件、檔案內的檔案、檔案內的檔案…每個檔案都需要查找其各自的 CD 進行解析。

邊註:簡單的當然這裡是相對的。

中央目錄記錄結束

就像存檔可以跨越多個磁碟一樣,CD 也可以。這中央目錄記錄結束儲存 CD 在哪個磁碟上開始和結束的資訊。如今,它通常是相同的磁碟,但有一個重要的說明,如果決定從規格中查看格式,則更容易理解。

(當然)這還有更多內容。一切都取決於一個人想要支持什麼。例如可以對資料進行加密。

如需完整閱讀,請查看應用筆記.TXT

了解 ZIP 存檔如何建立的基礎知識可以讓您更輕鬆地了解在使用 PHP Zip 等函式庫時可以做什麼和不能做什麼。


PHP 郵編

從未使用過它,但從它的外觀來看,它具有您需要的所有功能。猜測在詢問之前它不會讀取文件資料。看看這裡的範例#2:https://www.php.net/manual/en/zip.examples.php

在大型檔案上進行測試併計時。如果它只讀取 CD,即使是巨大的檔案,它也應該相對較快。


曾經為了好玩寫過一個 ZIP 解析器,但那是完全不同的故事了,哈哈。

相關內容