8

I am wondering if this is the best way to go about solving my problem.

I know the values for particular offsets of a binary file where the information I want is held...What I want to do is jump to the offsets and then read a certain amount of bytes, starting from that location.

After using google, I have come to the conclusion that my best bet is to use fseek() to move to the position of the offset, and then to use fread() to read an amount of bytes from that position.

Am I correct in thinking this? And if so, how is best to go about doing so? i.e. how to incorporate the two together.

If I am not correct, what would you suggest I do instead?

Many thanks in advance for your help.

Matt

Edit:

I followed a tutorial on fread() and adjusted it to the following:

    `#include <stdio.h>
    int main()
    {
      FILE *f;
      char buffer[11];
      if (f = fopen("comm_array2.img", "rt"))
      {
        fread(buffer, 1, 10, f);
        buffer[10] = 0;
        fclose(f);
        printf("first 10 characters of the file:\n%s\n", buffer);
      }
      return 0;
    }`

So I used the file 'comm_array2.img' and read the first 10 characters from the file.

But from what I understand of it, this goes from start-of-file, I want to go from some-place-in-file (offset)

Is this making more sense?

Edit Number 2:

It appears that I was being a bit dim, and all that is needed (it would seem from my attempt) is to put the fseek() before the fread() that I have in the code above, and it seeks to that location and then reads from there.

4

3 回答 3

3

如果您使用文件流而不是文件描述符,那么您可以自己编写一个类似于 POSIXpread()系统调用的(简单)函数。

您可以使用流而不是文件描述符轻松模拟它1。也许您应该为自己编写一个这样的函数(它的界面与我在评论中建议的界面略有不同):

size_t fpread(void *buffer, size_t size, size_t mitems, size_t offset, FILE *fp)
{
     if (fseek(fp, offset, SEEK_SET) != 0)
         return 0;
     return fread(buffer, size, nitems, fp);
}

这是pread()和的约定之间的合理折衷fread()


函数调用的语法是什么样的?例如,从偏移量 732 读取,然后再次从偏移量 432 读取(都从文件的开头)和调用的文件流f

由于您没有说要读取多少字节,我将假设每次 100。我假设目标变量(缓冲区)是buffer1and buffer2,并且它们都足够大。

if (fpread(buffer1, 100, 1, 732, f) != 1)
    ...error reading at offset 732...
if (fpread(buffer2, 100, 1, 432, f) != 1)
    ...error reading at offset 432...

返回计数是每个 100 字节的完整单元的数量;1(得到了一切)或 0(出了差错)。

还有其他编写该代码的方法:

if (fpread(buffer1, sizeof(char), 100, 732, f) != 100)
    ...error reading at offset 732...
if (fpread(buffer2, sizeof(char), 100, 432, f) != 100)
    ...error reading at offset 432...

每次读取 100 个单字节;测试确保您按预期获得了全部 100 个。如果您在第二个示例中捕获返回值,您可以知道您确实获得了多少数据。如果第一次读取成功而第二次读取失败,那将是非常令人惊讶的;其他一些程序(或线程)将不得不在两次调用之间截断文件fpread(),但已知会发生更有趣的事情。


1仿真不会完美;该pread()调用提供了保证的原子性,而组合fseek()不会fread()提供。但这在实践中很少会成为问题,除非您在尝试定位和读取文件时有多个进程或线程同时更新文件。

于 2012-03-25T19:57:17.893 回答
1

它通常取决于您关心的部件之间的距离。如果您只是跳过/忽略您关心的部分之间的几个字节,则通常更容易读取该数据并忽略您读取的内容,而不是使用fseek跳过它。执行此操作的典型方法是定义一个结构,其中包含您关心的数据和您不关心的数据的占位符,读入结构,然后只使用您关心的部分:

struct whatever {
   long a;
   long ignore;
   short b;
} w;

fread(&w, 1, sizeof(w), some_file);

// use 'w.a' and 'w.b' here.

但是,如果您关心的部分之间有很大的距离,那么您最初使用fseek来获取重要部分的想法可能会更简单。

于 2012-03-25T18:45:48.763 回答
0

你的理论听起来是正确的。打开,寻找,阅读,关闭。

为要读取的数据创建一个结构,并将指针传递给结构分配的内存的 read()。您可能需要在结构上使用 #pragma pack(1) 或类似的东西来防止错位问题。

于 2012-03-25T18:32:56.033 回答