在 c 中读取一个大的 bin 文件(~2mb)

reading a big bin-file(~2mb) in c

我想读取一个小于 2mb 的 bin 文件。

目前我读取bin文件的代码是这样的:

编辑:

#define MAX_BYTES_IN_FILE 500000         // ~ 2mb
#define ERROR_FILE 1

int get_byte_from_file(FILE *stream, unsigned char *dataarray) {
    int counter = 0;
                               
    while ((dataarray[counter] = fgetc(stream)) != EOF) {
        counter += 1;
    }
    return counter;
}

对于函数的示例使用,Main 看起来像这样。

int main(int argc, char **argv) {
    FILE *datei;
   
    unsigned int number_of_bytes;
    unsigned char *dataarray;

    dataarray = (unsigned char *)malloc(sizeof(unsigned char) * MAX_BYTES_IN_FILE);

    datei = fopen(argv[1], "rb");
   
    number_of_bytes = get_byte_from_file(datei, dataarray);
   
    for (int i = 0; i < number_of_bytes; i++)
        printf("%x ", dataarray[i]);
   
    return 0;
}

也许我犯了一个简单的错误但看不到错误仍然是:Segmentation fault (core dumped)

也许是这样的。

void *readfile(FILE *fi, long *filesize)
{
    void *buff;
    fseek(fi, 0, SEEK_END);
    *filesize = ftell(fi);
    fseek(fi, 0, SEEK_SET);
    buff = malloc(*filesize);
    if(buff)
    {
        fread(buff, 1, *filesize, fi);
    }
    return buff;
}

您需要添加错误检查 - 我没有,因为这只是想法。

以及您的用法:

int main(int argc, char **argv) {
 
   FILE *datei;
   
   long number_of_bytes;
   unsigned char *dataarray;

   datei=fopen(argv[1],"rb");
   
   dataarray = readfile(datei, &number_of_bytes);
   
   for (int i=0;dataarray && i<number_of_bytes;i++)
       printf("%hhx ",dataarray[i]);
   
   return 0;
}

您遇到分段错误的原因是您的分配不正确:您分配了 MAX_BYTES_IN_FILE 个字节而不是 unsigned int 个元素。分配后,数组只有 MAX_BYTES_IN_FILE / sizeof(unsigned int) 个元素,而文件可能有 MAX_BYTES_IN_FILE * sizeof(unsigned int) 个字节长。

您正在从文件中读取字节(值在 0255 之间)但是您使用了 unsigned int 元素。这是什么逻辑?文件是否包含 32 位值或单个字节?

一旦确认文件内容与数组在内存中的表示完全一致,就可以使用fread()一次调用读取整个文件。

这一行足以让你的程序崩溃:

while ((dataarray[counter] = fgetc(stream)) != EOF) {

让我们一步一步来:

  1. fgetc(stream) 读取一个字节和 returns 它的值或 EOF。因为一个字节可以有任何可能的值,fgetc() returns 一个更大的 int,它可以包含一个 EOF 值,该值不同于可能在文件。

  2. 您将此 int 值分配给 unsigned charEOF 值将被截断为此数据类型。

  3. 赋值的值为unsigned char类型,转换后的EOF值不再等于EOF。因此,比较总是会失败,并且您的程序会一直获取数据,直到缓冲区溢出和讨厌的事情开始发生。

您需要将 fgetc() 的结果存储在 int 变量中,直到您检查它确实不是 EOF 值。