Comment puis-je convertir un tampon binaire NodeJS en un ArrayBuffer JavaScript ?
Réponses
Trop de publicités?Utilisez l'excellent paquet npm suivant : to-arraybuffer
.
Ou bien, vous pouvez l'implémenter vous-même. Si votre tampon s'appelle buf
faites ça :
buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)
Vous pouvez penser à un ArrayBuffer
comme un Buffer
.
Un site ArrayBuffer
a donc toujours besoin d'un type (ce qu'on appelle la "vue du tampon de tableau"). Généralement, le Vue de la mémoire tampon d'un tableau a un type de Uint8Array
o Uint16Array
.
Il y a un bon article de Renato Mangini sur le site de la Commission européenne. conversion entre un ArrayBuffer et une chaîne (String) .
J'ai résumé les parties essentielles dans un exemple de code (pour Node.js). Il montre également comment convertir entre le code typographique ArrayBuffer
et le non typé Buffer
.
function stringToArrayBuffer(string) {
const arrayBuffer = new ArrayBuffer(string.length);
const arrayBufferView = new Uint8Array(arrayBuffer);
for (let i = 0; i < string.length; i++) {
arrayBufferView[i] = string.charCodeAt(i);
}
return arrayBuffer;
}
function arrayBufferToString(buffer) {
return String.fromCharCode.apply(null, new Uint8Array(buffer));
}
const helloWorld = stringToArrayBuffer('Hello, World!'); // "ArrayBuffer" (Uint8Array)
const encodedString = new Buffer(helloWorld).toString('base64'); // "string"
const decodedBuffer = Buffer.from(encodedString, 'base64'); // "Buffer"
const decodedArrayBuffer = new Uint8Array(decodedBuffer).buffer; // "ArrayBuffer" (Uint8Array)
console.log(arrayBufferToString(decodedArrayBuffer)); // prints "Hello, World!"
J'ai essayé la méthode ci-dessus pour un Float64Array et cela n'a pas fonctionné.
J'ai fini par me rendre compte qu'en réalité, les données devaient être lues "DANS" la vue en morceaux corrects. Cela signifie lire 8 octets à la fois depuis le tampon source.
Bref, voici ce que j'ai obtenu...
var buff = new Buffer("40100000000000004014000000000000", "hex");
var ab = new ArrayBuffer(buff.length);
var view = new Float64Array(ab);
var viewIndex = 0;
for (var bufferIndex=0;bufferIndex<buff.length;bufferIndex=bufferIndex+8) {
view[viewIndex] = buff.readDoubleLE(bufferIndex);
viewIndex++;
}
C'est pourquoi la réponse de Martin Thomson utilise Uint8Array, qui ne dépend pas de la taille des éléments. La réponse de Martin Thomson utilise Uint8Array. Buffer.read*
sont toutes lentes.
Plusieurs vues de tableaux typés peuvent référencer le même ArrayBuffer en utilisant la même mémoire. Chaque valeur d'un tampon est d'un octet, vous devez donc la placer dans un tableau dont la taille des éléments est d'un octet. Vous pouvez utiliser la méthode de Martin, puis créer un nouveau Float64Array en utilisant le même arraybuffer dans le constructeur.
Ce proxy exposera le tampon comme n'importe lequel des TypedArrays, sans aucune copie :
https://www.npmjs.com/package/node-buffer-as-typedarray
Il ne fonctionne que sur LE, mais peut être facilement porté sur BE. De plus, je n'ai jamais eu l'occasion de tester l'efficacité de ce système.
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les éléments essentiels de la réponse ici et de fournir le lien à titre de référence. Les réponses ne comportant qu'un lien peuvent devenir invalides si la page liée change.
Ma formulation n'est peut-être pas très officielle, mais elle fournit suffisamment d'informations pour recréer la solution. La solution s'appuie sur l'objet proxy JavaScript pour envelopper un tampon NodeJS natif avec les getters et setters utilisés par les TypedArrays. Cela rend l'instance de Buffer compatible avec toute bibliothèque qui nécessite l'interface Typed Array. C'est la réponse que l'auteur de l'article espérait, mais n'hésitez pas à la rejeter parce qu'elle ne correspond pas à votre jargon académique ou d'entreprise. Voyez si cela m'intéresse.
Il existe maintenant un paquet npm très utile pour cela : buffer
https://github.com/feross/buffer
Il essaie de fournir une API qui est 100% identique à l'API Buffer du nœud et le permet :
- convertit un tableau typé en tampon : https://github.com/feross/buffer#convert-typed-array-to-buffer
- convertit le tampon en tableau typé : https://github.com/feross/buffer#convert-buffer-to-typed-array
et quelques autres.
1 votes
Je suis curieux de savoir pourquoi vous avez besoin de faire ça ?
16 votes
Un bon exemple serait d'écrire une bibliothèque qui fonctionne avec les fichiers dans les navigateurs et aussi pour les fichiers NodeJS ?
1 votes
Ou en utilisant une bibliothèque de navigateur dans NodeJS
1 votes
Une autre raison est qu'un flottant prend trop d'octets de RAM lorsqu'il est stocké dans un fichier
Array
. Ainsi, pour stocker plusieurs flottants, il fautFloat32Array
où il prend 4 octets. Et si vous voulez une sérialisation rapide de ces flottants vers un fichier, vous avez besoin d'une fonctionBuffer
car la sérialisation en JSON prend du temps.0 votes
Je veux savoir exactement la même chose pour envoyer des données génériques en utilisant WebRTC et c'est incroyable que tant de réponses ici ont tant de likes, mais ne répondent pas à la question réelle....
1 votes
const file = fs.readFileSync(filePath);
alors comment je dois utiliser ça ?... 30 minutes plus tard, wow C me manque.