我必須以這種方式打包幾個文件,以便在稍後階段我可以使用c程序再次將它們解壓到原始文件,請建議。使用c打包文件,以便可以解壓縮到原始文件
回答
快速解決方案是利用外部庫如zLib(使用示例:http://zlib.net/zlib_how.html)並將其用於壓縮。
如果您想更深入地瞭解壓縮主題,請查看不同的無損壓縮算法,並進一步提示Wikipedia - Data compression。
我想對想要編寫自己的實現的解釋可能是好奇心。
無論您是否添加壓縮,如果您只是想將文件存儲在檔案中,類似於tar
命令,那麼您有幾種可能的方法。
您必須做出的基本選擇之一是:如何劃分檔案中壓縮文件的邊界?使用特殊字符並不是一個好主意,因爲打包文件可能包含任何開頭的字符。
要跟蹤文件的結尾,可以使用文件的長度(以字節爲單位)。例如,對於每個文件,您可以:
- 在檔案中寫入命名打包文件的'\ 0'終止的C字符串。
- 寫入存檔一個off64_t,它給出打包文件的長度(以字節爲單位)。
- 將打包文件的實際字節(如果有)寫入存檔。
- (可選)將歸檔文件的校驗和或CRC寫入歸檔。
對每個文件重複執行此操作,並將結果連接起來而不插入字符。
最後,當沒有文件時,寫一個空的C字符串,一個零字符。
拆包過程是:
- 閱讀「\ 0'結尾的C字符串,這個名字打包文件。
- 如果名稱爲空,則聲明我們已經讀取了整個存檔,然後退出。
- 閱讀提供打包文件長度的off64_t。
- 從存檔中讀取與打包文件長度一樣多的字節並寫入新創建的解壓縮文件。
再次重複這些步驟,直到步驟(2)結束程序。
這種設計中文件名與文件數據交替是可行的。它有一些缺點。基本問題是數據結構不是爲隨機訪問而設計的。爲了獲取檔案「中間」的文件信息,需要一個程序來處理前面的文件。程序可以調用lseek_64
跳過讀取不需要的程序數據,但處理器至少需要讀取每個文件名和每個文件長度。文件長度是跳過文件數據所必需的。在我排列數據時,必須讀取文件名以查找文件長度。
所以這是低效的。即使不必爲了訪問文件大小而讀取文件名,文件詳細信息被分散到整個存檔中的事實意味着讀取索引數據需要訪問磁盤上的多個範圍的數據。
更好的方法是將索引數據的「塊」寫入文件的前面。此數據結構可能類似於:
- 存檔中第一個文件的大小。
- 存檔中第一個文件的名稱。
- 位於此歸檔中的位置(以字節爲單位),其中「第一個文件」可能位於連續的字節塊中。
- 在歸檔中的第二個文件的大小...
和索引中的數據可能會重複,直到再次空名稱的文件標誌着索引的結束。
擁有這樣的索引很不錯,但會帶來一個難題:當用戶希望將文件附加到存檔時,索引可能需要增加大小。這可能會改變壓縮文件在壓縮文件中的位置 - 壓縮文件可能需要將它們移動以爲更大的索引騰出空間。
文件結構可以變得越來越複雜,以滿足所有這些不同的需求。例如,可以將索引設計爲始終從文件系統認爲的「頁面」(操作系統從磁盤讀取或寫入最小大小顆粒的量)中分配索引,並且如果索引需要增長,不連續的「索引頁」通過從一個索引頁導向另一個索引頁的文件位置數據鏈接在一起。 (就像鏈接列表一樣,但在磁盤上。)複雜性可以繼續下去。
我一對夫婦一天前寫像程序的焦油,在這裏我實現(希望你能得到一些想法): 每個文件都存儲在文件歸檔與「頭」,這是這樣的:
<file-type,file-path,file-size,file-mode>
在文件類型中,我使用0代表文件,使用1代表目錄(通過這種方式,您可以重新創建目錄樹) 例如,名爲foo.txt的文件頭大小爲245字節,模式爲0755 unix,看到chmod)將看起來像:
<0,foo.txt,245,0755>
here the file contents
以這種方式,文件存檔的第一個字符總是<,然後解析由逗號分隔的列表(第一個可能的錯誤)並提取文件類型,路徑,大小(您將使用它來讀取下一個大小字節從檔案 - 避免「特殊字符錯誤」由Heath Hunnicutt指出)和文件的模式(假設你有一個二進制文件,並且你也想在提取它時執行它,你需要用原始文件模式chmod它)。
關於第一個可能的錯誤,逗號不常用於文件名中,但最好使用另一個字符或「用一對夫婦」消毒路徑「」(對不起,我現在不記得名字,而英語不是我的母語),顯然解析器應該知道它,並忽略「」中的任何逗號。
對於在C中編寫和讀取文件,請參閱stdio中的fgetc和fputc。h 要獲取文件信息,chmod和目錄樹可以從sys/stat.h中看到stat和chmod,從ftw.h中看到ftw(可能是linux/unix,因爲是系統調用)。
希望它有幫助! (如果你需要一些代碼我可以發佈一些片段,頭文件解析可能是最難的部分)。
- 1. 是否可以包含壓縮文件中的JavaScript文件?
- 2. 在c#中使用zlib壓縮文件時解壓文件
- 3. PHP可以解壓縮使用.NET GZipStream類壓縮的文件嗎?
- 4. 使用C解壓縮.gz文件#
- 5. 使用c解壓縮文件#
- 6. 使用C#解壓縮tar/BZ2文件
- 7. 使用C#解壓縮tar文件
- 8. 解壓縮.Z文件C
- 9. 以kotlin腳本解壓縮文件[.kts]
- 10. 與django_compressor壓縮文件以gzip壓縮
- 11. 批處理文件到原始名稱的壓縮文件夾
- 12. 是否可以使用C#在FTP中壓縮文件夾?
- 13. 通過C#使用cmd來壓縮和解壓縮文件
- 14. 解壓縮文件
- 15. 解壓縮文件
- 16. 使用ZipFile類從多個文件的zip壓縮文件解壓縮文件
- 17. 將壓縮文件解壓縮到內存流 - C#
- 18. 在iphone中以編程方式解壓文件並解壓縮文件?
- 19. 解壓縮文件用PHP
- 20. 用PHP壓縮文件解壓後得到cpgz文件
- 21. 是否可以壓縮或壓縮.otf(Open Type Face)文件?
- 22. 我可以使用VBA使用本機窗口解壓縮功能解壓縮文件嗎?
- 23. 使用PPMD壓縮的Zip文件,以編程方式解壓縮
- 24. 將LastWriteTime設置爲解壓縮文件的原始時間戳
- 25. 如何打包/加密/解壓縮/ Java解密一堆文件?
- 26. 可以proguard混淆原始文件名
- 27. 如何解壓文件夾並刪除壓縮的原件?
- 28. 如果可以進一步壓縮angular2 Js包文件
- 29. 可以使用DeflateStream或GZipStream來壓縮未壓縮的文件嗎?
- 30. Node.js - 壓縮/解壓縮文件夾
你有沒有聽說過「拉鍊」? – Pointy 2011-03-06 15:24:33