我有4個問題:
- 是否可以掃描整個 zip 檔案並在其中導航,而無需使用 PHP 提取整個 zip?
- 時間效率會高嗎?即我有一個大約 50GB 的 zip 文件,其中包含許多小文件(尤其是過去的許多圖像),我想使用 PHP 製作一個文件瀏覽器。
- 這可以遞歸地完成嗎,即如果我在一個大拉鍊中有很多拉鍊,我能夠解析它們嗎?
- 如果我可以解析 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 解析器,但那是完全不同的故事了,哈哈。