Leyendo una estructura binaria en Javascript
Tengo una tabla que estoy tratando de leer en Javascript, con datos lo suficientemente grandes como para querer tenerlos en formato binario para ahorrar espacio. La mayoría de la tabla son números o enumeraciones, pero hay algunos datos que son cadenas de texto. Estoy tratando de encontrar la mejor manera de leer esos datos en Javascript. ¿Algún consejo?
Por cierto, la versión comprimida en texto tiene ~33 MB, mientras que el archivo binario comprimido tiene ~20 MB, por eso estoy tratando de reducir el tamaño, con la esperanza de que cargue más rápido. Estoy planeando realizar un preprocesamiento de los datos con Python, lo cual reducirá los datos a solo lo que realmente me importa. Puede que esté filtrando algunos de estos datos, pero idealmente me gustaría tener un sitio web estático, por lo que prefiero no depender de ningún código en el servidor. El archivo que tiene casi cualquier cosa importante tiene solo ~1 MB, así que no creo que sea un gran inconveniente.
Puntos extra si el sistema permite un flotante de 16 bits, ya que hay varios flotantes donde 16 bits es más que suficiente precisión para capturar adecuadamente.
Mi código, por simple que sea hasta ahora, es el siguiente. Tenga en cuenta el bloque faltante donde ocurre algo útil…
function loadBinaryFloatArray(url) {
var mRequest = new XMLHttpRequest();
mRequest.open('GET', url);
mRequest.responseType = 'arraybuffer';
mRequest.onreadystatechange = function () {
if (this.readyState === 4) {
}
};
mRequest.send();
}
console.log("Test")
loadBinaryFloatArray("/data/sbdb_important.bin")
Los datos se ven algo así. Tenga en cuenta que probablemente eliminaré algunas de estas columnas, pero estos son los datos fuente. Para referencia, solo la primera columna se almacenará como una cadena de texto, los otros se pueden almacenar como números o enumeraciones convertidas a números. Probablemente habrá dos cadenas de texto reales, creo que voy a dividir la cadena en sus dos partes.
Para referencia, el código de Python para empacar es el siguiente. Puedo cambiar las ‘e’ por algo más si es necesario, ya sea float32 o un entero que se convierte en decimal, pero sería bueno tener compatibilidad nativa.
struct.pack('ehifeefff', diameter, type, epoch, a, e, i, om, w, ma)
davy.ai
Una posible solución para leer los datos binarios con cadenas de texto en JavaScript es utilizar TypedArrays. Los TypedArrays te permiten leer y escribir datos binarios en un formato específico. Puedes utilizar las API TextEncoder y TextDecoder para convertir entre cadenas de texto y sus representaciones de bytes correspondientes. Aquí tienes un ejemplo de cómo leer datos binarios con cadenas de texto utilizando TypedArrays:
En este ejemplo, se asume que los datos binarios están en un formato específico, con los primeros 8 bytes que contienen el número de filas y columnas como enteros sin signo de 32 bits en orden de bytes little-endian. Se asume que los datos restantes contienen los datos de la tabla en orden mayor-fila, donde todos los datos numéricos se almacenan como valores de coma flotante de 32 bits en orden de bytes little-endian, y todos los datos de cadena se almacenan como una secuencia de bytes UTF-8 terminada en null.
Para escribir los datos binarios en Python, puedes utilizar el módulo
struct
para empaquetar los datos en el formato deseado, y luego guardarlo como un archivo binario. Aquí tienes un ejemplo:En este ejemplo, los datos se empaquetan en formato binario como floats de 32 bits utilizando el código de formato
f
, y los bytes resultantes se convierten en unFloat32Array
en JavaScript. Luego, se utiliza la funciónconvertFloat32ToFloat16
para convertir cada float de 32 bits en un float de 16 bits extrayendo su signo, exponente y fracción, y empaquetándolos en un solo entero de 16 bits utilizando el formato de coma flotante de media precisión IEEE. El array resultante de floats de 16 bits se almacena como unUint16Array
.</iiffff6siffff6s’,>