转到C中二进制文件的某个点(使用fseek),然后从该位置读取(使用fread)

转到C中二进制文件的某个点(使用fseek),然后从该位置读取(使用fread),c,binary,fread,fseek,C,Binary,Fread,Fseek,我想知道这是否是解决我问题的最好方法 我知道保存我想要的信息的二进制文件的特定偏移量的值…我要做的是跳转到偏移量,然后从该位置开始读取一定数量的字节 使用google之后,我得出结论,我的最佳选择是使用fseek()移动到偏移量的位置,然后使用fread()从该位置读取大量字节 我这样想对吗?如果是这样的话,那么最好的做法是什么?i、 e.如何将两者结合在一起 如果我不正确,你会建议我怎么做 非常感谢你的帮助 马特 编辑: 我遵循了有关fread()的教程,并将其调整为以下内容: `#i

我想知道这是否是解决我问题的最好方法

我知道保存我想要的信息的二进制文件的特定偏移量的值…我要做的是跳转到偏移量,然后从该位置开始读取一定数量的字节

使用google之后,我得出结论,我的最佳选择是使用fseek()移动到偏移量的位置,然后使用fread()从该位置读取大量字节

我这样想对吗?如果是这样的话,那么最好的做法是什么?i、 e.如何将两者结合在一起

如果我不正确,你会建议我怎么做

非常感谢你的帮助

马特

编辑:

我遵循了有关fread()的教程,并将其调整为以下内容:

    `#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;
    }`
`include
int main()
{
文件*f;
字符缓冲区[11];
如果(f=fopen(“comm_array2.img”、“rt”))
{
fread(缓冲器,1,10,f);
缓冲区[10]=0;
fclose(f);
printf(“文件的前10个字符:\n%s\n”,缓冲区);
}
返回0;
}`
所以我使用了文件“comm_array2.img”并读取了文件的前10个字符

但据我所知,这是从文件开始的,我想从文件中的某个地方开始(偏移量)

这更有意义吗

编辑编号2:


看起来我有点糊涂,需要做的就是(从我的尝试看来)将fseek()放在上面代码中的fread()之前,然后它寻找那个位置,然后从那里读取。

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


为要读取的数据创建一个要读取的结构,并将指针传递给该结构的已分配内存的read()。您可能需要在结构上安装#pragma pack(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
获取重要部分的想法可能会更简单。

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

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

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


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

既然你没说要读多少字节,我假设每次读100字节。我假设目标变量(缓冲区)是
buffer1
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()
组合不会提供的保证原子性。但在实践中,这很少会成为问题,除非您在尝试定位和读取文件时有多个进程或线程同时更新文件。

是的。使用fseek()和fread()。你试过什么代码?是的,你是对的,但是你的问题是什么?网上有教程介绍如何使用它们。使用搜索词“fseekfreadc教程”,应该可以直接找到一些。你做过什么吗?查一下系统调用。使用流而不是文件描述符来模拟它。也许您自己编写了一个函数,例如:
ssize\t fpread(char*buffer,size\t nbytes,size\t offset,FILE*fp)
。如果您的平台支持它,您可以使用
pread()
,它可以同时执行这两个操作。谢谢您,我正要请您进一步查看您的评论,您抢先了我的发言权,谢谢。因此,如果我理解正确,我将创建该函数,并以与我最初使用pread相同的方式使用它,并将文件名(而不是文件描述符)和偏移量传递给它?有点……您的评论提到了文件名,但
fread()
fseek()
都不能使用文件名;这就是fopen()的工作。
fpread()
函数几乎可以替代
fseek()
fread()
调用。显然,如果您想让它使用文件名,您必须
fopen()
和(大概)
fclose()
函数中的文件,并且您不会传递
fpif (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...