【问题标题】:C: read binary file to memory, alter buffer, write buffer to fileC:读二进制文件到内存,改变缓冲区,写缓冲区到文件
【发布时间】:2011-07-05 07:11:08
【问题描述】:

目标: 打开包含二进制数据的文件,将整个文件读入内存,更改文件的某些部分,将内存缓冲区写入文件,关闭文件。利润?

问题: 我刚刚开始学习 C,但我找不到足够的信息来说明如何在内存缓冲区中更改为二进制数据。来自网络开发人员背景(php、python、as3),这对我来说是一个新领域。

上下文: 我有一个函数,它获取文件的路径和指向 char 指针内存缓冲区的指针地址。然后它打开文件,遍历文件并将数据写入内存缓冲区。最后关闭文件。

二进制文件的目的是保存一些对象的类别ID,它们的位置是它们自己的ID。类别 ID 表示为 2 字节短。所以本质上它只是一个二进制文件,里面有很多我希望能够读取和更改的短裤。

这是我目前得到的:

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;
}

二进制处理程序.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. 有没有办法让我以详细的方式检查缓冲区中的值?

总而言之,我只是想帮助我掌握整个概念,这样我就可以自己解决这个问题。

谢谢!

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

【问题讨论】:

    标签: c file memory binary


    【解决方案1】:

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

    注意:您为 fread 指定的参数是向后的。第二个参数是你正在阅读的类型的大小,应该是sizeof(char)。第三个参数应该是您要读取的字符数,应该是fileSize。不过,您的代码仍然有效,但它表示当您读取 fileSize 字节长的 fileSize 对象时,它想读取 1 字节长的 fileSize 对象。

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

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

    您可以像这样将短片写回文件:

    buffer[2] = n >> 0;
    buffer[3] = n >> 8;
    

    3)fwrite

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

    【讨论】:

    • 1.好的,我删除了循环。 2. 我的意思是二进制列表中的第二个对象。例如,如果文件有 2 个值,则文件将以 hexedit 形式显示:“01 00 11 00”。我的意思是,如何更改缓冲区中的第二个值(11 00)? 3. 好的,那么只需传入整个缓冲区?没有转换或来自char的任何东西? 4. 我只是想要一种显示缓冲区的方法,以便检查它是否正确。所以如果你除了我在main上面添加的函数还有其他方法。
    • 感谢您为我清除了所有问题,但仍然没有给我一个完整的解决方案。非常感谢:)
    猜你喜欢
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多