C:关于如何从存档文件中提取文件的理论

时间:2010-12-22 15:13:24

标签: c

在C中,我创建了一个程序,可以通过命令行将多个文件存档到存档文件中。 e.g。

$echo 'file1/2' > file1/2.txt
$./archive file1.txt file2.txt arhivedfile
$cat archivedfile 
file1
file2

如何创建流程,以便在我的归档文件中:

header
file1
end
header
file2
end

它们一个接一个地存储在存档文件中。我知道可能需要一个头文件(包含文件名,文件名大小,文件的开头和结尾),以便将这些文件提取回原始形式,但我该怎么做呢。

我被困在哪里以及如何开始。

请有人帮我解决一些关于如何从归档文件中提取文件的逻辑。

4 个答案:

答案 0 :(得分:3)

如前所述,从算法开始。你已经掌握了大部分细节。

您可以采取一些方法:

  1. 随机存取档案。
  2. 顺序访问存档。
  3. 随机存取存档

    为了使其工作,标题需要充当索引(如库中的卡索引),指示; (a)在哪里找到每个文件的开头; (b)每个档案的长度。编写存档文件的算法可能如下所示:

    1. 从命令行获取所有文件的列表。
    2. 创建一个结构来保存有关每个文件的元数据:name(255 char),size(64位int),日期和时间以及权限。
    3. 对于每个文件,获取其统计信息。
    4. 将每个文件的统计信息存储在结构数组中。
    5. 打开存档进行编写。
    6. 编写标题结构。
    7. 对于每个文件,将其内容附加到存档文件。
    8. 关闭存档文件。
    9. (标题可能也必须包含文件数。)

      接下来,提取文件的算法:

      1. 从命令行获取存档文件。
      2. 从命令行获取要提取的文件名。
      3. 为结构创建内存以读取有关每个文件的元数据。
      4. 从存档文件中读取所有元数据。
      5. 搜索要在整个元数据列表中提取的文件名。
      6. 计算匹配文件名开头的存档文件的偏移量。
      7. 寻找抵消。
      8. 读取文件内容并将其写入新文件。
      9. 关闭新文件。
      10. 关闭存档。
      11. 顺序访问

        这更容易。你可以自己做:仔细考虑一下步骤。

        关于编程

        很容易陷入 某些东西应该如何运作的细节中。我建议你退后一步 - 老师应该在课堂上讨论这个问题 - 并尝试在编码之上考虑问题,因为:

        • 您创建的算法将与语言无关;
        • 在编写代码之前修复算法中的错误是微不足道的;
        • 在编码之前,您将更好地了解您需要做什么;
        • 实施解决方案所需的时间更短;
        • 您可以识别可以并行实施的区域;
        • 你会提前看到任何潜在的障碍;和
        • 您将立即前往管理职位。 ; - )

答案 1 :(得分:1)

我认为标题需要具有识别文件所需的信息以及文件在存档中的大小 - 例如,文件名,原始目录以及行或字节中的大小,具体取决于哪个更多在您的上下文中有用。然后,您需要例程来创建标题,将文件添加到存档(创建标题并附加文件数据),从存档中提取文件(按照标题直到找到正确的条目并从中复制数据)存档到单独的文件),并删除文件(开始读取存档,将除要删除的条目之外的所有条目的数据复制到新文件,然后删除旧存档并将新存档重命名为旧名称)。

分享并享受。

答案 2 :(得分:1)

一种方法是模仿ZIP格式:http://en.wikipedia.org/wiki/ZIP_file_format

它使用文件末尾的目录结构,其中包含指向存档中文件偏移量的指针。这种结构的最大好处是,您可以在不必读取整个存档的情况下找到给定文件 - 只要您知道目录的开头并且能够随机访问该文件。

另一种选择是TAR文件格式:http://en.wikipedia.org/wiki/Tar_file_format

这是专为流媒体(“磁带存档”)设计的,因此每个条目都包含自己的元数据。您必须扫描整个文件以查找条目,但正常的用例是打包/解压缩整个目录树,因此这不是一个很糟糕的惩罚。

答案 3 :(得分:1)

像tar一样以流式方式执行它可能是最简单的实现。首先,写出一个幻数,以便您可以确定这是您的存档格式。然后我建议使用stat(2)(这是stat手册页的man语法,第2节)来获取要归档的文件的大小。实际上,仔细查看可用的统计字段,您可能希望保留一些有趣的信息。

以tag = value方式写出您需要的信息,每行一个。例如:

FileName=file1.txt
FileSize=10
FileDir=./blah/blah
FilePerms=0700

使用两个换行符结束标题,以便知道何时开始将FileSize字节推送到磁盘。您不需要标头标记的开头,因为您知道要写出的文件大小,因此您知道何时再次开始解析标题。

我建议您使用文本格式作为标题信息,因为如果您将原始二进制结构写入磁盘,则不必担心字节排序等问题。

读取存档时,逐个解析标题行并填充本地结构以保存该信息。然后将文件写出到磁盘,并根据您提取的标题信息设置任何需要更新的文件属性。

希望有所帮助。祝你好运。