¿“Mejores” formatos de archivo de entrada para C++?
json sqlite (4)
Estoy empezando a trabajar en una nueva pieza de software que terminará necesitando un archivo de E / S robusto y expandible. Hay muchos formatos por ahí. XML, JSON, INI, etc. Sin embargo, siempre hay ventajas y desventajas, así que pensé que le pediría algo a la comunidad.
Aquí hay algunos requisitos aproximados:
- El formato es un "estándar" ... No quiero reinventar la rueda si no tengo que hacerlo. No tiene que ser un estándar formal de IEEE, pero algo que podría buscar en Google y obtener información como nuevo usuario puede tener algunas herramientas de soporte (editores) más allá de vi. (Aunque los usuarios de software generalmente serán expertos en computadoras y estarán felices de usar vi.)
- Se integra fácilmente con C ++. No quiero tener que usar una biblioteca de 100 mb y tres compiladores diferentes para ponerlo en funcionamiento.
- Admite entrada tabular (2d, n-dimensional)
- Soporta tipos de POD
- Se puede expandir a medida que se requieren más entradas, se enlaza bien con las variables, etc.
- La velocidad de análisis no es terriblemente importante
- Idealmente, tan fácil de escribir (reflejar) como leer
- Funciona bien en Windows y Linux
- Admite la composición (un archivo hace referencia a otro archivo para leer, etc.)
- Legible para humanos
En un mundo perfecto, usaría una biblioteca de solo encabezado o alguna implementación STL limpia, pero estoy bien con el uso de Boost o alguna pequeña biblioteca externa si funciona bien.
Entonces, ¿qué piensas sobre varios formatos? Inconvenientes? Ventajas?
Editar
Opciones a considerar? ¿Algo más para agregar?
- XML
- YAML
- SQLite
- Google Protocol Buffers
- Impulsar la serialización
- INI
- JSON
Después de haber trabajado bastante con XML y json, he aquí mi opinión subjetiva de ambos como formatos de serialización ampliables:
- El formato es un "estándar": Sí para ambos
- Se integra fácilmente con C ++: Sí para ambos. En cada caso, probablemente terminará con algún tipo de biblioteca para manejarlo. En Linux, libxml2 es un estándar, y libxml ++ es un contenedor de C ++ para él; deberías poder obtener ambos del administrador de paquetes de tu distro. Tomará un pequeño esfuerzo para que los que trabajan en Windows. Parece que hay algún soporte en Boost para json, pero no lo he usado; Siempre he tratado con json usando bibliotecas. Realmente, la ruta de la biblioteca no es muy onerosa para ninguno de los dos.
- Admite entrada tabular (2d, n-dimensional): Sí para ambos
- Soporta tipos de POD: Sí para ambos
- Se puede expandir a medida que se requieren más entradas: Sí para ambos, esa es una gran ventaja para ambos.
- Se une bien a las variables: si lo que quiere decir está de alguna manera dentro del archivo en sí mismo para decir " Este dato debe deserializarse automáticamente en esta variable en mi programa", entonces no para ambos.
- Tan fácil de escribir (reflexionar) como de leer: depende de la biblioteca que use, pero según mi experiencia, sí para ambos. (De hecho, puedes hacer un trabajo tolerable al escribir json usando printf ()).
- Funciona bien en Windows y Linux: Sí para ambos, y lo mismo ocurre con Mac OS X.
- Admite un archivo que hace referencia a otro archivo para leer: si te refieres a algo similar a un C #include, entonces XML tiene cierta capacidad para hacer esto (por ejemplo, entidades de documento), mientras que json no lo hace.
- Legible para humanos: ambos están escritos típicamente en UTF-8, y permiten saltos de línea y sangría, y por lo tanto pueden ser legibles por humanos. Sin embargo, acabo de trabajar con un archivo XML de 479 KB que está en una sola línea, así que tuve que ejecutarlo a través de una bonita impresora para darle sentido. json también puede ser bastante ilegible, pero en mi experiencia a menudo se formatea mejor que XML.
Al iniciar nuevos proyectos, generalmente prefiero json; Es más compacto y más legible para los humanos. La principal razón por la que podría seleccionar XML en lugar de json sería si me preocupara recibir documentos mal formados, ya que XML admite la validación automática de formatos de documentos, mientras que usted tiene que escribir su propio código de validación con json.
Echa un vistazo a los buffers de google . Esto se encarga de la mayoría de sus necesidades.
De su documentación , los pasos de alto nivel son:
Definir formatos de mensaje en un archivo .proto.
Usa el compilador de buffer de protocolo.
Utilice la API de búfer de protocolo C ++ para escribir y leer mensajes.
Hay un formato excelente que cumple con todos sus criterios:
SQLite!
Lea el article sobre el uso de SQLite como formato de archivo de aplicación. Además, vea Google Tech Talk de D. Richard Hipp (autor de SQLite) sobre este tema.
Ahora, veamos cómo SQLite cumple con sus requisitos:
El formato es un "estándar".
SQLite se ha convertido en el formato de elección para la mayoría de los entornos móviles y para muchas aplicaciones de escritorio (Firefox, Thunderbird, Google Chrome, Adobe Reader, lo que sea).
Se integra fácilmente con C ++
SQLite tiene una interfaz C estándar , que es solo un archivo de origen y un archivo de encabezado. También hay envoltorios de C ++ .
Admite entrada tabular (2d, n-dimensional)
La tabla de SQLite es tan tabular como usted podría imaginar. Para representar, por ejemplo, datos tridimensionales, cree una tabla con las columnas x,y,z,value
y almacene sus datos como un conjunto de filas como esta:
x1,y1,z1,value1
x2,y2,z2,value2
...
Soporta tipos de POD
Supongo que por POD te refieres a los datos antiguos y sencillos o BLOB. SQLite le permite almacenar los campos BLOB como es.
Se puede expandir a medida que se requieren más entradas, se une bien a las variables
Aquí es donde realmente brilla.
La velocidad de análisis no es terriblemente importante
Pero la velocidad de SQLite es excelente. De hecho, el análisis es básicamente transparente.
Idealmente, tan fácil de escribir (reflejar) como leer
Simplemente use INSERT
para escribir y SELECT
para leer: ¿qué podría ser más fácil?
Funciona bien en Windows y Linux
Usted apuesta, y todas las demás plataformas también.
Admite la composición (un archivo hace referencia a otro archivo para leer)
Puedes adjuntar una base de datos a otra.
Legible para humanos
No en binario, pero hay muchos excelentes navegadores / editores SQLite por ahí. Me gusta SQLite Expert Personal en Windows y sqliteman en Linux. También hay un plugin de editor de SQLite para Firefox .
Hay otras ventajas que SQLite te da gratis:
Los datos son indexables lo que hace que la búsqueda sea muy rápida. Simplemente no puede hacer esto utilizando XML, JSON o cualquier otro formato de solo texto.
Los datos se pueden editar parcialmente , incluso cuando la cantidad de datos es muy grande. No es necesario volver a escribir algunos gigabytes solo para editar un valor.
SQLite es totalmente transaccional : garantiza que sus datos sean consistentes en todo momento. Incluso si su aplicación (o toda la computadora) falla, sus datos se restaurarán automáticamente al último estado consistente conocido en el próximo primer intento de conectarse a la base de datos.
SQLite almacena sus datos literalmente : no necesita preocuparse por el escape de caracteres basura en sus datos (incluyendo cero bytes incrustados en sus cadenas), simplemente use declaraciones preparadas , eso es todo lo que se necesita para hacerlo transparente. Esto puede ser un problema grande y molesto cuando se trata de formatos de datos de texto, en particular XML.
SQLite almacena todas las cadenas en Unicode :
UTF-8
(predeterminado) oUTF-16
. En otras palabras, no necesita preocuparse por las codificaciones de texto o el soporte internacional para su formato de datos.SQLite le permite procesar datos en trozos pequeños (fila a fila, de hecho), por lo que funciona bien en condiciones de poca memoria . Esto puede ser un problema para cualquier formato basado en texto, porque a menudo necesitan cargar todo el texto en la memoria para analizarlo. Por supuesto, hay pocos analizadores XML eficientes basados en flujo por ahí, pero en general cualquier analizador XML será bastante codicioso en comparación con SQLite.
Para mis propósitos, creo que el camino a seguir es XML .
- El formato es un estándar, pero permite la modificación y flexibilidad para que el esquema cambie a medida que los requisitos del programa evolucionen.
- Hay varias opciones de biblioteca. Algunos son más grandes (Xerces-C), algunos son más pequeños (ezxml), pero hay muchas opciones, por lo que no estaremos atados a un solo proveedor o una solución muy específica.
- Puede soportar entrada tabular (2d, n-dimensional). Esto requiere más trabajo de análisis en "nuestro" final, y probablemente sea el punto más débil para XML.
- Soporta tipos de POD: Absolutamente.
- Puede expandirse a medida que se requieren más entradas, se vincula bien a las variables, etc. mediante modificaciones de esquema y modificaciones del analizador.
- La velocidad de análisis no es terriblemente importante, por lo que procesar un archivo de texto o archivos no es un problema.
- XML puede ser programado tan fácilmente como leído.
- Funciona bien en Windows y Linux o en cualquier otro sistema operativo que admita archivos C y de texto.
- Admite la composición (un archivo hace referencia a otro archivo para leer, etc.)
- Legible por humanos con muchos editores de texto (Sublime, vi, etc.) que admiten resaltado de sintaxis fuera de la caja. Muchos navegadores web muestran bien los datos.
Gracias por todos los buenos comentarios! Creo que si quisiéramos una solución puramente binaria, Protocol Buffers o boost :: serialización es probablemente la forma en que iríamos.