Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

309
Vistas
Cómo manejar problemas de portabilidad en un formato de archivo binario

Estoy diseñando un formato de archivo binario para almacenar cadenas [sin terminar nulo para ahorrar espacio] y datos binarios.

i. ¿Cuál es la mejor manera de lidiar con sistemas little/big endian? ia ¿Funcionaría la conversión de todo a orden de bytes de red y viceversa con ntohl()/htonl()?

ii. ¿Serán las estructuras empaquetadas del mismo tamaño en x86, x64 y brazo?

iii. ¿Hay alguna debilidad inherente con este enfoque?

 struct __attribute__((packed)) Header { uint8_t magic; uint8_t flags; }; struct __attribute__((packed)) Record { uint64_t length; uint32_t crc; uint16_t year; uint8_t day; uint8_t month; uint8_t hour; uint8_t minute; uint8_t second; uint8_t type; };

Código de prueba que estoy usando para desarrollar el formato:

 #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <limits.h> #include <strings.h> #include <stdint.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> struct __attribute__((packed)) Header { uint8_t magic; uint8_t flags; }; struct __attribute__((packed)) Record { uint64_t length; uint32_t crc; uint16_t year; uint8_t day; uint8_t month; uint8_t hour; uint8_t minute; uint8_t second; uint8_t type; }; int main(void) { int fd = open("test.dat", O_RDWR|O_APPEND|O_CREAT, 444); struct Header header = {1, 0}; write(fd, &header, sizeof(header)); char msg[] = {"BINARY"}; struct Record record = {strlen(msg), 0, 0, 0, 0, 0, 0, 0}; write(fd, &record, sizeof(record)); write(fd, msg, record.length); close(fd); fd = open("test.dat", O_RDWR|O_APPEND|O_CREAT, 444); read(fd, &header, sizeof(struct Header)); read(fd, &record, sizeof(struct Record)); int len = record.length; char c; while (len != 0) { read(fd, &c, 1); len--; printf("%c", c); } close(fd); }
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

i. Definir el archivo para que esté en un orden y convertirlo hacia y desde un orden "interno", si es necesario, al leer/escribir (quizás con ntohl y similares) es, en mi opinión, el mejor enfoque.

ii. No confío en las estructuras empaquetadas. Podrían funcionar para este enfoque para esas plataformas, pero no hay garantías.

iii. Leer y escribir archivos binarios usando fread y fwrite en estructuras completas es (de nuevo en mi opinión) un enfoque inherentemente débil. Maximiza la probabilidad de que le molesten problemas de tamaño de palabra, problemas de relleno y alineación, y problemas de orden de bytes.

Lo que me gusta hacer es escribir pequeñas funciones como get16() y put32() que leen y escriben un byte a la vez y, por lo tanto, son intrínsecamente insensibles al tamaño de la palabra y las dificultades del orden de los bytes. Luego escribo funciones sencillas putHeader y getRecord (y similares) en términos de estas.

 unsigned int get16(FILE *fp) { unsigned int r; r = getc(fp); r = (r << 8) | getc(fp); return r; } void put32(unsigned long int x, FILE *fp) { putc((int)((x >> 24) & 0xff), fp); putc((int)((x >> 16) & 0xff), fp); putc((int)((x >> 8) & 0xff), fp); putc((int)(x & 0xff), fp); }

[PD Como @Olaf señala correctamente en uno de los comentarios, en el código de producción necesitaría el manejo de EOF y error en estas funciones. Los he dejado fuera por simplicidad de presentación.]

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda