2011-02-27 119 views
5

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

问题: 我刚开始学习C和我无法找到有关如何更改为二进制数据存储在存储器缓冲区足够的信息。来自web开发者背景(php,python,as3)对我来说这是一个新领域。

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

二进制文件的目的是为某些对象保存category-ids,它们的位置是它们自己的id。 category-ids表示为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; 
} 

二进制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; 
    } 
} 

将这个代码产生的第一步(正在读取文件到内存)?

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

3.如何获取缓冲区并将其写回文件?

4.有没有办法让我以冗长的方式检查缓冲区中的值?

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

谢谢!

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

回答

2

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

注意:您为fread指定的参数是向后的。第二个参数是您正在阅读的类型的大小,应该是sizeof(char)。第三个参数应该是你想要读取的字符数量,应该是fileSize。但是,您的代码仍然有效,但它表示要在读取fileSize字节长度为1字节的对象时读取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)我不明白你在问什么。

+0

1.好的,我删除了循环。我的意思是二进制列表中的第二个对象。例如,如果文件有2个值,则文件将以hexedit格式查看:“01 00 11 00”。我的意思是,我如何改变缓冲区中的第二个值(11 00)?好的,那么只需传入整个缓冲区呢?没有转换或任何字符?我只是想要一种显示缓冲区的方法,以便检查它是否正确。所以如果你有任何其他的方式比我在主要上面添加的功能。 – rzetterberg 2011-02-27 17:10:27

+0

感谢您为我清理所有内容,但仍未给我一个完整的解决方案。非常感激 :) – rzetterberg 2011-02-27 17:34:10