2011-02-27 25 views
5

El objetivo: Abrir un archivo con datos binarios, leer todo el archivo en la memoria, cambiar algunas partes del archivo, escribir el búfer de memoria en el archivo, cierra el archivo. ¿Lucro?C: leer el archivo binario en la memoria, alterar el búfer, escribir el búfer en el archivo

El problema: Acabo de empezar a aprender C y no puedo encontrar suficiente información sobre cómo cambiar a los datos binarios en la memoria intermedia. Viniendo de un fondo de desarrollador web (php, python, as3), este es un nuevo territorio para mí.

Contexto: Tengo una función que lleva la ruta al archivo y una dirección de puntero a un búfer de memoria de puntero de carácter. A continuación, abre el archivo, recorre el archivo y escribe datos en el búfer de memoria. Finalmente cierra el archivo.

El propósito del archivo binario es mantener identificadores de categoría para algunos objetos y su posición es su propia identificación. Los ID de categoría se representan como cortos de 2 bytes. Entonces, básicamente, es solo un archivo binario lleno de muchos cortos que quiero poder leer y cambiar.

Esto es lo que tengo hasta ahora:

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

binaria-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. Será este código producirá el primer paso (leyendo el archivo en la memoria) correctamente?

2. En caso afirmativo, ¿cómo puedo cambiar, por ejemplo, el segundo objeto en la memoria intermedia para tener un valor de 0F 00?

3. ¿Cómo puedo tomar el búfer y volver a escribirlo en el archivo?

4. ¿Hay alguna manera de verificar los valores en el búfer de forma detallada?

En general, solo quiero ayuda para entender todo el concepto, así que puedo resolverlo yo solo.

Gracias!

Editar: Se eliminó el bucle del archivo. Se agregó una función que imprime todo el buffer.

Respuesta

2

1) No. No necesita hacer un bucle en getFileBuffer ya que ha leído todo el archivo con fread. Tampoco necesita llamar al fseek porque cada vez que lea del archivo avanzará automáticamente dentro de la secuencia de archivos. No depuré el código, pero parece que para cuando termine el bucle, cada elemento del búfer contendrá el mismo valor y será igual a lo que sea el último byte en su archivo.

Nota: Los argumentos especificados para fread son al revés. El segundo parámetro es el tamaño del tipo que está leyendo, que debería ser sizeof(char). El tercer parámetro debe ser la cantidad de caracteres que desee leer, que debería ser fileSize.Sin embargo, su código aún funciona, pero dice que quiere leer 1 objeto que es fileSize bytes de largo cuando está leyendo fileSize objetos que son 1 byte de longitud.

2) Puede leer el segundo valor a corto como esto (en Little Endian):

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

Puede escribir el corto de nuevo al archivo así:

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

3) fwrite

4) No entiendo lo que está preguntando.

+0

1. De acuerdo, eliminé el bucle. 2. Me refiero al segundo objeto en la lista binaria. Por ejemplo, si el archivo tiene 2 valores, el archivo se verá en un hexedit: "01 00 11 00". Lo que quise decir fue, ¿cómo cambio el segundo valor (11 00) en el búfer? 3. Ok, entonces solo pasa todo el búfer? Sin conversión ni nada de char? 4. Solo quería una forma de mostrar el buffer para poder verificar que fuera correcto. Entonces, si tiene alguna otra forma que no sea la función que agregué arriba, principal. – rzetterberg

+0

Gracias por aclararme todo y aún no darme una solución completa. Muy apreciado :) – rzetterberg

Cuestiones relacionadas