我必须以这种方式打包几个文件,以便在稍后阶段我可以使用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