7 Stimmen

C: Binärdatei in den Speicher lesen, Puffer ändern, Puffer in Datei schreiben

Das Ziel: Öffnen einer Datei mit binären Daten, Lesen der gesamten Datei in den Speicher, Ändern einiger Teile der Datei, Schreiben des Speicherpuffers in die Datei, Schließen der Datei. Gewinn?

Das Problem: Ich habe gerade angefangen, C zu lernen, und ich kann nicht genügend Informationen darüber finden, wie man Binärdaten in den Speicherpuffer umwandelt. Aus einem Web-Entwickler Hintergrund (php, Python, as3) ist dies Neuland für mich.

Der Kontext: Ich habe eine Funktion, die den Pfad zur Datei und eine Zeigeradresse zu einem Char-Pointer-Speicherpuffer nimmt. Sie öffnet dann die Datei, durchläuft die Datei in einer Schleife und schreibt Daten in den Speicherpuffer. Schließlich wird die Datei geschlossen.

Der Zweck der Binärdatei ist es, Kategorie-IDs für einige Objekte zu speichern und ihre Position ist ihre eigene ID. Die Kategorie-IDs werden als 2-Byte-Kurzbefehle dargestellt. Im Wesentlichen handelt es sich also um eine Binärdatei, die mit vielen Kurzzeichen gefüllt ist, die ich lesen und ändern können möchte.

Hier ist, was ich bis jetzt habe:

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. Wird dieser Code den ersten Schritt (Lesen der Datei in den Speicher) korrekt ausführen?

2. Wenn ja, wie kann ich das 2. Objekt im Puffer so ändern, dass es einen Wert von 0F 00 hat?

3. Wie kann ich den Puffer nehmen und ihn in die Datei zurückschreiben?

4. Gibt es eine Möglichkeit, die Werte im Puffer in einer ausführlichen Weise zu überprüfen?

Alles in allem möchte ich nur Hilfe, um das ganze Konzept zu verstehen, damit ich das Problem selbst lösen kann.

Danke!

Bearbeiten: Die Schleifenbildung in der Datei wurde entfernt. Eine Funktion hinzugefügt, die den gesamten Puffer ausgibt.

2voto

Marlon Punkte 19311

1) Nein. Sie müssen keine Schleife in getFileBuffer da Sie die gesamte Datei mit fread . Sie müssen auch nicht anrufen fseek denn jedes Mal, wenn Sie aus der Datei lesen, bewegen Sie sich automatisch innerhalb des Dateistroms weiter. Ich habe Ihren Code nicht überprüft, aber es sieht so aus, als ob nach Abschluss der Schleife jedes Element im Puffer denselben Wert enthält und dem letzten Byte in Ihrer Datei entspricht.

Hinweis: Die Argumente, die Sie für fread angegeben haben, sind rückwärts gerichtet. Der zweite Parameter ist die Größe des Typs, den Sie lesen, die sein sollte sizeof(char) . Der dritte Parameter sollte die Anzahl der Zeichen sein, die Sie lesen möchten. fileSize . Ihr Code funktioniert zwar immer noch, aber er sagt, dass er Folgendes lesen will 1 Objekt, das fileSize Bytes lang, wenn Sie lesen fileSize Objekte, die 1 Byte lang.

2) Sie können den zweiten kurzen Wert wie folgt lesen (in Little Endian):

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

Sie können den Kurztext wie folgt in die Datei zurückschreiben:

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

3) fwrite

4) Ich verstehe nicht, worauf Sie hinauswollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X