C语言:读取二进制文件到内存,修改缓冲区,将缓冲区写入文件

7
目标: 打开一个包含二进制数据的文件,将整个文件读入内存,更改文件的某些部分,将内存缓冲区写入文件,关闭文件。赚取利润? 问题: 我刚开始学习C语言,无法找到足够的关于如何在内存缓冲区中更改二进制数据的信息。作为一个网络开发者(php、python、as3),这对我来说是新的领域。 背景: 我有一个函数,它接收文件路径和指向字符指针内存缓冲区的指针地址。然后它打开文件,在文件中循环并将数据写入内存缓冲区。最后关闭文件。
二进制文件的目的是保存一些对象的类别ID,它们的位置就是它们自己的ID。类别ID表示为2字节shorts。因此,它实际上只是一个充满了许多shorts的二进制文件,我希望能够读取和更改其中的内容。
以下是我目前拥有的内容:
main.c:
#include "binary-handler.h"

void showFileBuffer(char *buffer, unsigned int fileSize){
    int i = 0;
    for(; i < fileSize; ++i){
        printf("<%d:%x>\n", i, ((char *)buffer)[i]);
    }
}

int main(){
    char path[] = "assets/map-squares.bin";
    char *buffer;
    int fileSize;
    fileSize = readFileToMemory(path, &buffer);
    showFileBuffer(buffer, fileSize);

    //Code to change buffer
    //Code to write buffer to file
    return 0;
}

binary-handler.c:

#include <stdio.h>
#include <stdlib.h>

unsigned int getFileSize(FILE **file){
    unsigned int size;
    if(fseek(*file, 0, SEEK_END) == -1){ return -1; }
    size = ftell(*file);
    fseek(*file, 0, SEEK_SET);
    return size;
}

char *getFileBuffer(FILE **file, unsigned int fileSize){
    char *buffer = malloc(fileSize + 1);
    fread(buffer, fileSize, 1, *file);
    return buffer;
}

unsigned int readFileToMemory(char path[], char **buffer){
    unsigned int fileSize;

    FILE *file = fopen(path, "rb");
    if(file != NULL){
        fileSize = getFileSize(&file);
        *buffer = getFileBuffer(&file, fileSize);
        fclose(file);
        return fileSize;
    }else{
        *buffer = NULL;
        return -1;
    }
}

1. 这段代码能正确地执行第一步(将文件读入内存)吗?

2. 如果是,我该如何更改缓冲区中的第二个对象的值为0F 00?

3. 如何将缓冲区写回文件?

4. 是否有一种方式可以以详细的方式检查缓冲区中的值?

总之,我只是想要帮助理解整个概念,以便自己解决问题。

谢谢!

编辑:删除了文件的循环。添加了一个打印整个缓冲区的函数。

1个回答

2

1) 不需要在getFileBuffer函数中使用循环,因为你使用fread函数读取了整个文件。也不需要调用fseek函数,因为每次从文件中读取数据时,文件流会自动向前移动。我没有调试过你的代码,但看起来当循环完成时,缓冲区中的每个元素都将包含相同的值,并且它将等于文件中的最后一个字节。

注意:你指定给fread函数的参数是反过来的。第二个参数是你要读取的类型的大小,应该是sizeof(char)。第三个参数应该是你想要读取的字符数,应该是fileSize。虽然你的代码仍然可以工作,但实际上它想要读取一个长度为fileSize字节的对象,而你正在读取fileSize个长度为1字节的对象。

2) 你可以这样读取第二个短整型值(小端):

short n = 0;
n |= buffer[2] << 0;
n |= buffer[3] << 8;

您可以像这样将简短的内容写回文件中:
buffer[2] = n >> 0;
buffer[3] = n >> 8;

3) fwrite

fwrite()函数可用于向文件写入二进制数据。语法是:
fwrite($file, $data, $length)

4) 我不明白你在问什么。


  1. 好的,我已经移除了循环。
  2. 我指的是二进制列表中的第二个对象。例如,如果文件有两个值,在十六进制编辑器中文件将显示为:"01 00 11 00"。我的意思是,如何更改缓冲区中的第二个值(11 00)?
  3. 好的,那么只需传入整个缓冲区?不需要从char进行任何转换吗?
  4. 我只是想要一种显示缓冲区的方法,以便我可以检查它是否正确。所以,如果你有任何其他方法,而不是我在main函数上面添加的函数。
- rzetterberg
非常感谢你为我澄清了一切,尽管没有给我一个完整的解决方案。非常感激 :) - rzetterberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接