日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

7z文件格式及其源码的分析(四)

發布時間:2023/12/20 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 7z文件格式及其源码的分析(四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是7z文件格式及其源碼的分析系列的第四篇. 上一篇講到了7z文件靜態結構的尾header部分.這一篇開始,將從7z實際壓縮流程開始詳細介紹7z文件尾header的詳細結構.

一, 第一個概念: coder.

在7z的壓縮過程中, 一個非常核心的概念就是coder. ?一個coder代表一個算法, 通常是指一個壓縮或解壓算法(也包括過濾算法和加密算法等). 例如, 在7z中lzma算法就是一個coder, ?deflate算法也是一個coder. ?7z中用于加密的AES256算法也是一個coder. ?

所以概念上講, 能處理一個文件流的算法就是一個coder. ?這個"處理"的概念可以是壓縮/解壓, 加密等等.

(圖1)

通常來講, 一個coder只能處理一個輸入流, 并且只有一個輸出流. ?比如把一個文件流壓縮成一個輸出流. ?但是, 7z中有的coder可以把一個輸入流處理成多個輸出流, 反過來也可以把多個流處理成一個流. 比如7z的 BCJ2 coder, ?它是一個過濾coder, 可以把一個exe文件過濾成四個輸出流. ?這樣的話, 7z的coder概念得到了擴展. ?就是可能同時處理多個輸入流, 并且可能輸出多個流:

(2)

這里可以先簡單的體驗一下壓縮的過程了:

1. 簡單壓縮過程, ?把文件流交給lzma coder壓縮.

(圖3)

2. 多coder串聯, 理論上可以串聯任何兩個coder, 而且串聯的級數也是沒有限制的, 可以串聯任意多級. 當然, 由于熵的存在, 串聯過個壓縮coder是沒有意義的.

這里示例的是最常用的一種方式,就是壓縮并且加密.

(圖4)

注意上圖中的o1, 和 i2. ? o1是第一個coder的輸出流, i2是第二個coder的輸入流. 在實際操作中, 這兩個流其實是同一個流, 直接把第一個的輸出當做第二個的輸入.

解壓的過程就是上面的逆過程.

上圖就是比較完整的一次壓縮過程了.

?

二, 第二個概念 Folder, 不是文件夾.

這里的Folder要特別注意, ?它不是我們通常指的文件夾. ?它也不是任何物理上存在的東西. ?

7z在開始壓縮之前, 會把文件分類, ?大體上是按文件類型以及文件是否需要加密來分類的. ? 比如說, 把所有的exe文件分成一類(一個Folder), 或者把所有需要加密的文件分在一起. 等等. 具體分類方法以后再說. ?這個分類方法并不重要, 7z的實現用的方法比較簡單. 實際上如果要實現7z的壓縮器的話, 這個分類方法你說了算. 你可以給每個文件劃分成一個Folder.

?我們看一個例子:

(圖5)

?在這個例子中, 我們共有5個文件需要壓縮.?

1. 首先, 通過一定的分組方法, 我們分成了兩個Folder, ?第一個Folder包括: a.exe, b.exe 和 c.dll 三個文件. ?第二個Folder包括:a.txt 和 b.txt.

2. 對Folder1來說, 它包含三個文件, Folder1就簡單的把三個文件串聯起來,當做一個大文件, 作為輸入流 i1 給Coder1 用. 后面的過程就就是上面的 圖4 的內容了.

在7z源碼的:?\CPP\7zip\Archive\7z\ 這個目錄下,有?7zFolderInStream.h 和7zFolderInStream.cpp 專門處理把多個文件串聯偽裝成一個文件的任務. 從Coder1 的角度看, 它只知道有個文件流 i1, 并不知道這個i1 是一個真實的文件 還是由一個Folder偽裝的.

?

實際上, 7z概念上最小的壓縮單位不是文件, 而是Folder, ?它會先把所有的文件都歸到一個相應的Folder中, 然后 讓這個Folder作為文件流, 流過若干個Coder. ?我們再抽象一下上面的壓縮過程:

(圖 6)

上圖中的字母 'i' 表示輸入的意思, 'o' 表示輸出. 后面的數字表示序號. ? 簡單解釋一下, 這個Folder流最初是作為Coder1 的輸入流i1. Coder1 的輸出流是o1. 這個o1又作為 i2 輸入給Coder2用, ?然后又是Coder3. ? ?

值得注意的是最后一個coder的輸出流 o3. ?它就是壓縮的最終輸出結果了. ?它在7z中叫做一個PackedStream. 就是打包的流. ?我們叫做p1吧. ?如果有多個Folder, 那每個Folder就會有一個或多個PackedStream. ?所以所有文件壓縮之后就會有 pn. ?這n個packedStream會被按順序存儲在 7z的文件主體, 就是上一篇文章中介紹的第二部分.

?

每個Folder 包含了哪些文件, 每個文件大小等等這些詳細信息都存貯在7z的尾文件頭中了. 在7zformat.txt中有這一段:

NumFoldersFolders[NumFolders]{NumCodersCodersInfo[NumCoders]{IDNumInStreams; //表示這個coder 所接受的輸入流的個數, 一般是1個NumOutStreams; //表示這個coder的輸出流的個數, 一般是1個.PropertiesSize //一個int值, 表示后面Properties的字節長度Properties[PropertiesSize] // 字節數組, 表示這個coder的一些設置信息, 比如壓縮級別, 或者AES加密的IV等等. }NumBindPairs // 表示bindpair 的個數. bindpair表示輸入流和輸出流的綁定關系. 例如上面的圖6中, o1和i2是綁定的, o2和i3是綁定的.BindPairsInfo[NumBindPairs] //bindpair的數組, 記錄每一個bindpair.{InIndex; //這個綁定的輸入index, 就是上圖中對應的 i后面的序號. (不好意思, 畫圖的時候沒注意,圖上下表是從1開始的,但是實際上,你懂的, 都是從0開始的.所有上面圖中的下標都要減一.)OutIndex; //綁定對應的輸出index, 就是對應上圖中o后面的序號. 同上. }PackedIndices //這表示這個folder最終輸出的packstream在所有packstream中的序號.}UnPackSize[Folders][Folders.NumOutstreams] // 這是一個二位數組, 記錄每個Folder對應的輸出流的個數.CRCs[NumFolders] //這是一個Crc的數組, 沒個folder 流的crc, 7z目前沒有使用這一個字段.

稍微解釋一下上面的結構:

1.?NumFolders, 顯示一個int32值, 它記錄了7z文件中共有多少個Folder.

2. 后面那是folder數組, 一次排布每個Folder. 每個Folder結構如下:

3.?NumCoders, int32值, 記錄了這個Folder總共進過了幾個coder.

4. 后面就是它的所有Coder的數組, 每個coder的結構: ?顯示一個coder 的id. 就是coder的唯一標示符. 這個id的定義在:?DOC/目錄下的 methods.txt.?

5. 更詳細的信息, 請看上面代碼后面的注釋吧.

6. 我再強調一點,我畫圖的時候沒有注意,所以圖中的i和o后面的序號都是從1開始的, 實際上,你懂的, 每個存儲的序號都是從0開始的, 沒有例外. 如果你發現哪里的序號和我說的不一樣, 請檢查這個. ?沒有例外, 所有的序號都是從0開始的. 包括以后我可能會畫的圖. 記住都是從0開始的.

?

7, 再有一點就是, 比如上圖中的folder經過了 coder1, coder2 和coder3 這三個coder. 實際才存儲這三個coder的時候, 是按逆序存儲的, 就是先存Coder3, 然后是coder2, 最后是coder1. ?這是為了方便解壓.

?

?

上面的圖6就是一次比較完整的壓縮流程, ? ?解壓的流程就是反過來, 先分別構建coder1, coder2 和coder3, 然后逆向流動就最終解壓了.

每個Folder都會經過一次完整的壓縮過程.

?

好了, 主要的壓縮過程和結構已經介紹完了. ? 下一篇將給大家介紹剩下的文件詳細信息的存儲方式, 以及最終的Header的生成方式.

最后還是歡迎大家訪問我的獨立博客: http://byNeil.com?

?

寫這么多字, 畫圖都不容易, ?幫頂一下吧, 小伙伴們.

?

?

?

轉載于:https://www.cnblogs.com/shuidao/p/3307300.html

總結

以上是生活随笔為你收集整理的7z文件格式及其源码的分析(四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。