【问题标题】:Read/Write files in C用 C 读/写文件
【发布时间】:2012-10-18 21:49:17
【问题描述】:

我正在用 C 编写一个程序,它基本上为给定的文件名列表创建一个存档文件。这与 linux 中的ar 命令非常相似。这是存档文件的样子:

!<arch>
file1.txt/      1350248044  45503 13036 100660  28        `
hello
this is sample file 1
file2.txt/      1350512270  45503 13036 100660  72        `
hello
this is sample file 2
this file is a little larger than file1.txt

但我在尝试从存档中提取文件时遇到了困难。假设用户想要提取file1.txt。想法是它应该获取文件名的索引/位置(在本例中为 file1.txt),跳过 58 个字符以到达文件的内容,读取内容,并将其写入新文件。所以这是我的问题:

1) 如何获取存档文件中文件名的索引/位置?请注意,不允许有重复的文件名,所以我不必担心有两个不同的问题。

2) 如何在读取文件时跳过多个字符(本例中为 58 个字符)?

3) 如何判断文件内容何时结束?即我需要它来阅读内容并在 file2.txt/ 标头之前停止。

【问题讨论】:

  • 不清楚这里使用的是什么存档格式。那是存档文件的显示吗?或者它可能是另一个工具的显示?
  • 是时候选择答案种类了?
  • 存档文件是我发布的。它应该是这样设计的,我需要想办法从中获取信息。

标签: c unix-ar


【解决方案1】:

我解决这个问题的方法是:

要有一个包含每个文件的大小、名称和在文件中的位置的标题信息。

然后解析标题,使用fseek() and ftell() 以及fgetc()fread() 函数来获取文件的字节,然后创建+写入该数据到它。这是我能想到的最简单的方法。

http://en.wikipedia.org/wiki/Ar_(Unix)#File_header

示例: @programmer93 考虑您的标头长度为 80 个字节(标头包含存档文件的元数据)。您有两个文件,一个是 112 字节,另一个是 182 字节。现在它们被放置在一个平面文件(存档文件)中。所以它将是 80(header).112(file1.txt).182(file2.txt).EOF 。因此,如果您知道每个文件的大小,则可以轻松导航(使用 fseek())到特定文件并仅提取该文件。 [提取 file2.txt 我将只 fseek(FILE*,(112+80),SEEK_SET); 然后 fgetc() 182 次。我想我说清楚了吗?

【讨论】:

  • 嗯,我在存档文件中确实有文件的大小和名称,它的顺序与常规 ar 文件完全相同,但不是位置。而且我不太明白以这种方式获取文件的字节会有什么帮助。
  • 我需要确保我了解 fseek()、ftell() 和 fgetc() 的工作原理。我以前从未使用过它们中的任何一个。
  • codingunit.com/c-tutorial-binary-file-io 检查这个@programmer93 的二进制 i/o
  • 我仍然不知道如何获取文件中字符串的位置:/
  • 这就是标题的用途。 @程序员93。它们会告诉您有关在何处找到文件的信息。
【解决方案2】:

如果无法通过添加额外的标题信息来更改文件的格式以提供帮助,则您必须搜索它并随时解决问题。

这应该不会太难。只需读取文件,当您读取标题行时,例如

file1.txt/      1350248044  45503 13036 100660  28        `

您可以检查文件名和大小等(您知道在!&lt;arch&gt; 之后的开头会有一个标题行)。如果这是您想要的文件,stdio.h 中的 ftell() 函数会告诉您您在文件中的确切位置。由于文件大小以字节为单位在标题行中给出,您可以通过以正常方式提前读取特定数量的字节来读取文件。同样,如果不是您想要的文件,您可以使用fseek() 将您正在跳过的文件中的字节数向前移动,并准备好读取下一个文件的标题信息并重复该过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2013-05-23
    • 2015-05-24
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多