Ver Mensaje Individual
  #2 (permalink)  
Antiguo 12/11/2013, 12:02
vosk
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: A vueltas con un archivo binario

Pues eso, lo que te indica la descripcion: primero te saltas los 2 bytes que no tienen significado, luego lees 8, luego saltas 1, luego lees 2, etc...

Por orden, primero abres el archivo:

Código C:
Ver original
  1. FILE *arx;
  2. if(!(arx = fopen(path, "rb"))) {
  3.     //error de acceso
  4. }

Ahora saltas 2 bytes:

Código C:
Ver original
  1. fseek(arx, 2L, SEEK_CUR);

Lees 8 bytes:

Código C:
Ver original
  1. //necesitas declarar el double
  2. double julian_date;
  3. fread(&julian_date, sizeof(double), 1, arx);

Saltas otro byte:

Código C:
Ver original
  1. fseek(arx, 1L, SEEK_CUR);

Lees la amplitud:

Código C:
Ver original
  1. //necesitas declarar el short
  2. short int amplitude;
  3. fread(&amplitude, sizeof(short int), 1, arx);

Y asi vas leyendo hasta terminar el primer record; luego haces lo mismo para el segundo. Ten en cuenta que para cada lectura tienes que hacer las comprovaciones de error necesarias, incluso por si el archivo estuviera mal escrito y terminara antes de tiempo.

Alternativamente está la forma serializada que consiste en guardar los tipos en una estructura y leer estructuras enteras, p.ej.:

Código C:
Ver original
  1. struct RECORD {
  2.     char internal_a[2];
  3.     double julian_time;
  4.     char internal_b;
  5.     short int amplitude;
  6.     etc...
  7. };

Solo te pongo los primeros pero ya ves de que va la cosa. Ahora en vez de leer campo por campo puedes leer toda la estructura:

Código C:
Ver original
  1. //necesitas declarar una estructura
  2. struct RECORD record;
  3. //reseteas los campos
  4. memset(&record, 0, sizeof(struct RECORD));
  5. //y lees el record
  6. fread(&record, sizeof(struct RECORD), 1, arx);

De esta forma en una sola lectura recuperas todo un record.

Lo siguiente es saber cuantos recors contiene el archivo. Sabiendo lo que ocupan todos los tipos, es decir sabiendo lo que ocupa la estructura RECORD, solo tienes que dividir el tamaño del archivo por el tamaño del record, tienes que obtener un numero entero, de lo contrario el archivo está mal construido. Primero recuperas el tamaño:

Código C:
Ver original
  1. size_t file_size;
  2. fseek(arx, 0L, SEEK_END);
  3. file_size = ftell(arx);
  4. fseek(arx, 0L, SEEK_SET);

Luego lo divides por el tamaño de la estructura:

Código C:
Ver original
  1. int n_records = file_size / sizeof(struct RECORD);

Ahora ya sabes cuantos records has de leer.

Y si quieres implementar los tipos indicados en la referencia solo tienes que redefinir los tipos que te comenté como los tipos indicados:

Código C:
Ver original
  1. typedef char BYTE;
  2. typedef short int WORD;
  3. typedef double REAL;

De esta forma puedes reescribir la estructura con los tipos redefinidos:

Código C:
Ver original
  1. struct RECORD {
  2.     BYTE internal_a[2];
  3.     REAL julian_time;
  4.     BYTE internal_b;
  5.     WORD amplitude;
  6.     etc...
  7. };

Saludos
vosk