C: чтение двоичного файла в память, изменение буфера, запись буфера в файл - PullRequest
5 голосов
/ 27 февраля 2011

Цель: Открыть файл с двоичными данными, прочитать весь файл в память, изменить некоторые части файла, записать в файл буфер памяти, закрыть файл.Прибыль?

Проблема: Я только начал изучать C и не могу найти достаточно информации о том, как перейти к двоичным данным в буфере памяти.Исходя из опыта веб-разработчиков (php, python, as3), это новая территория для меня.

Контекст: У меня есть функция, которая берет путь к файлу и адрес указателя на буфер памяти указателя символа.Затем он открывает файл, просматривает файл и записывает данные в буфер памяти.Наконец закрывает файл.

Цель двоичного файла - хранить идентификаторы категорий для некоторых объектов, а их позиция - их собственный идентификатор.Идентификаторы категорий представлены как 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;
}

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. Если да, как я могу изменить, скажем, 2-й объект в буфереимеют значение 0F 00?

3. Как взять буфер и записать его обратно в файл?

4. Есть ли способ для меня, чтобы проверить значения в буфере в подробном виде?

В общем, я просто хочу помочь понять всю концепцию, чтобы я мог решить это сам.

Спасибо!

Редактировать: Удалено зацикливание файла.Добавлена ​​функция, которая печатает весь буфер.

1 Ответ

2 голосов
/ 27 февраля 2011

1) Нет. Вам не нужно зацикливаться на getFileBuffer, так как вы прочитали весь файл с помощью fread.Вам также не нужно вызывать fseek, потому что каждый раз, когда вы читаете из файла, вы автоматически продвигаетесь в файловом потоке.Я не отлаживал ваш код, но, похоже, к тому времени, когда ваш цикл завершится, каждый элемент в буфере будет содержать одно и то же значение, и оно будет равно любому последнему байту в вашем файле.

Примечание: Аргументы, которые вы указали для fread, задом наперед.Второй параметр - это размер читаемого вами типа, который должен быть sizeof(char).Третьим параметром должно быть количество символов, которые вы хотите прочитать, которое должно быть fileSize.Ваш код все еще работает, но он говорит, что хочет прочитать 1 объект длиной 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

4) Я не понимаю, о чем вы спрашиваете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...