Estoy a punto de comenzar a escribir un proceso para guardar parte de la estructura de datos del código en un archivo de algún tipo propietario, aún no definido. Sin embargo, nunca antes había diseñado un tipo o estructura de archivo.
- ¿Hay alguna cosa, en general, que debería considerar antes de comenzar mi diseño?
- ¿Hay alguna buena práctica aceptada aquí? ¿Malas prácticas que debo evitar?
- ¿Qué hacer y qué no hacer absoluto?
design
file-structure
Andy Hunt
fuente
fuente
Respuestas:
Primero, trate de encontrar un formato lo suficientemente cercano a lo que está a punto de construir. En general, es mejor usar el formato de alguien que inventar el suyo, incluso si el formato parece ser un poco más complejo de lo que necesita 1 .
Si no puede encontrar un formato listo para usar adecuado, vea si puede crear uno propio sobre un formato de propósito general existente, como XML o XML binario . Esto debería ser posible en casi todos los casos cuando esté a punto de comenzar un nuevo formato de archivo. El XML basado en texto ocupa más espacio, pero le da a los humanos cierta capacidad de lectura. Sin embargo, si se encuentra utilizando la codificación Base-64 dentro de un archivo XML, es una clara indicación de que debería haber utilizado una codificación binaria.
En cuanto a las buenas y malas prácticas, asegúrese de no "incorporar" la función de hardware de su plataforma de destino inicial en el diseño de su formato de archivo. Específicamente, asegúrese de que sus números estén almacenados en un formato que pueda leerse correctamente en plataformas con una capacidad de escritura diferente a la del escritor, y que sus cadenas orientadas al usuario estén almacenadas en UNICODE.
Otra buena práctica es incluir un encabezado desde el cual es posible determinar el tipo de su archivo en caso de que su extensión no esté o sea incorrecta. Es una buena idea incluir una versión de su formato de archivo en el encabezado. Esto le permitiría cambiar el formato más adelante y seguir siendo compatible con versiones anteriores.
Si es posible, no haga que su formato dependa de los detalles del mecanismo de serialización predeterminado integrado en su plataforma. Por ejemplo, los objetos Java binarios serializados no tienen un buen formato de archivo 2 .
Finalmente, decida si sus archivos deben ser transferibles . Esto introduce una complejidad adicional, porque uno debería ser capaz de interpretar "fotogramas" individuales de su archivo de forma aislada. Sin embargo, en los casos en que necesita capacidad de transmisión, casi siempre debería poder localizar un formato de archivo adecuado que ya exista.
1 Por otro lado, debe evitar los formatos que requieren esfuerzos extraordinarios para soportar la complejidad que requiere su aplicación.
2 Sin embargo, esto no significa que no deba intentar integrar de forma personalizada la lectura y escritura de su nuevo formato con el esquema de serialización de su plataforma, solo que no debe confiar en los mecanismos predeterminados de serialización.
fuente
Lo primero que debe considerar es si realmente necesita un nuevo formato o si puede obtenerlo utilizando un formato ya existente. Considere usar SQLite; Si puede adaptar sus necesidades al modelo RDBMS, esto podría ahorrarle muchos dolores de cabeza. Además, considere usar XML o JSON, esto le ahorrará tener que escribir su propio analizador.
Si tiene que crear su propio formato, la primera consideración es si desea un formato de texto o un formato binario. Hay ventajas para ambos. Un formato de texto es una gran victoria para la portabilidad y tiene la ventaja de ser más fácil de leer o editar para un humano. Un formato binario podría ser más eficiente, pero tiene muchos problemas de portabilidad. No sienta la tentación de leer bytes directamente en variables, lo lamentará si necesita portar el código a otra plataforma.
fuente
Su primera y más importante decisión es usar un formato binario o uno basado en texto. Binario es el camino a seguir cuando tiene que volcar grandes cantidades en datos que no son cadenas. Pero tiene desventajas significativas:
Los datos binarios no son legibles por humanos. Como tal, hace que la depuración y / o ajuste de datos que ya están en el disco sea mucho más difícil. Esta es una de las razones por las cuales la filosofía de UNIX abarca tan fuertemente los archivos basados en texto.
Los formatos binarios no se prestan para una futura expansión. Si bien esto se puede hacer, los puntos para la capacidad de expansión deben integrarse en el formato desde el principio. Por lo general, estos son
un número mágico / cadena que identifica el formato
un número de versión de formato
campos reservados en posiciones estratégicas, que deben inicializarse a cero
Los primeros dos generalmente aparecen justo al comienzo del archivo, mientras que los campos reservados generalmente se encuentran dispersos en el archivo.
Ahora, si sigue la ruta basada en texto, aquí hay algunas cosas en las que pensar:
Cualquier formato basado en texto define un nuevo mini idioma. Sepa esto y úselo para su ventaja.
Intenta mantener las reglas de tu mini-idioma lo más simple posible. No hay lugar donde el principio KISS sea más importante que cuando se diseña un formato de archivo basado en texto.
Intenta que tus archivos se expliquen por sí mismos.
No imponga restricciones innecesarias, como dónde puede aparecer el espacio en blanco y cuánto.
Eche un vistazo a varios formatos de archivo diferentes desarrollados para UNIX. Esto puede darle algunas buenas ideas.
Si es posible, use o adapte / expanda / restrinja un formato de archivo existente. El formato json es un buen punto de partida bastante legible. (Al menos mucho mejor que XML, que es un dolor de leer para los humanos).
Si el tamaño del archivo es un problema, puede considerar usar un formato basado en texto de todos modos, pero páselo a través de uno de los compresores estándar como
gzip
olzma
. Los compresores estándar aman la entrada de esa manera.Si va por la ruta binaria, aquí hay algunas cosas a tener en cuenta:
Debe tener un encabezado con un número / cadena mágico y un número de versión. Por lo general, esto va al principio del archivo, pero también puede ir al final del archivo. Algunos archivos incluso pueden tener dos encabezados diferentes en la parte delantera y trasera, lo que brinda dos vistas independientes de los datos que contiene.
Debe tener un índice y debe tratar de mantener sus partes juntas. Esto le permite al lector descubrir rápidamente qué hay dentro del archivo, sin tener que escanear todo. Si no lo haces, podrías terminar leyendo todo dos veces.
Si tiene bits del archivo a los que solo se puede acceder como una secuencia en lugar de a través de una estructura de índice, incluya al menos un campo de longitud para cada registro en la secuencia. Un índice o tales campos de longitud son requisitos para los lectores que no entienden todos los detalles de su formato y necesitan omitir partes de él como cuadros negros. (Gracias a Jules por este.)
Cada objeto de datos dentro del archivo debe contener al menos un campo reservado para una futura expansión. Esto no necesita ser grande, pero debe estar allí. Porque, si no es así, no hay lugar donde pueda reconocer las características futuras.
Debe tener en cuenta la resistencia. Por lo general, eso significa que usted decide una vez si sus archivos deben codificarse en orden de bytes big endian o little endian, y se adhiere a esa decisión: manejar la endianess como esta es una molestia, pero no es tan malo como tener que tener en cuenta dos versiones diferentes de endianess en el archivo.
Sea generoso en el ancho de los campos que proporcione. Especialmente, cuando necesite codificar desplazamientos dentro del archivo, use siempre 64 bits. Los diseñadores de formatos de archivo han causado muchos dolores de cabeza que fueron demasiado conservadores con la cantidad de bits que asignaron.
fuente
Realmente depende de lo que estés haciendo. Debe ser lo más simple posible y no más simple. Veo a muchas otras personas empujando XML. Desaconsejo firmemente el uso de XML. XML es un desorden sobre especificado. La primera pregunta sería si sus estructuras de datos tienen ramas. ¿Qué significan listas de listas o listas de mapas o algo así? Si no, entonces una secuencia simple de registros de texto podría ser buena. CSV tal vez.
Si necesita rendimiento o acceso aleatorio, binario es bueno. Defina una secuencia de registros donde cada registro contenga una secuencia de datos que tengan un tamaño específico como un entero pequeño endian de 4 bytes para algún número o un entero de 2 bytes que especifique el número de bytes para una cadena UTF-8. Haga que cada registro comience con un número entero que especifique el tamaño del registro para que se pueda escanear todo el archivo sin leer realmente el contenido de los registros. Esto también le permite codificar registros in situ (lo que significa que puede mapear el archivo, codificar el registro y luego actualizar el tamaño después para minimizar la copia innecesaria). Este es el tipo de cosas que no puedes hacer con XML.
fuente