Recherche…


Remarques

Les tableaux ont été tapées spécifiées à l' origine par le projet d'un éditeur Khronos et standardisé plus tard dans ECMAScript 6 §24 et §22.2 .

Les blobs sont spécifiés par le brouillon de travail de l'API de fichier W3C .

Conversion entre Blobs et ArrayBuffers

JavaScript a deux façons principales de représenter des données binaires dans le navigateur. ArrayBuffers / TypedArrays contient des données binaires mutables (mais de longueur fixe) que vous pouvez manipuler directement. Les blobs contiennent des données binaires immuables accessibles uniquement via l'interface de fichier asynchrone.

Convertir un Blob en un ArrayBuffer (asynchrone)

var blob = new Blob(["\x01\x02\x03\x04"]),
    fileReader = new FileReader(),
    array;

fileReader.onload = function() {
    array = this.result;
    console.log("Array contains", array.byteLength, "bytes.");
};

fileReader.readAsArrayBuffer(blob);
6

Convertir un Blob en un ArrayBuffer utilisant une Promise (asynchrone)

var blob = new Blob(["\x01\x02\x03\x04"]);

var arrayPromise = new Promise(function(resolve) {
    var reader = new FileReader();

    reader.onloadend = function() {
        resolve(reader.result);
    };

    reader.readAsArrayBuffer(blob);
});

arrayPromise.then(function(array) {
    console.log("Array contains", array.byteLength, "bytes.");
});

Convertir un ArrayBuffer ou un tableau typé en un objet Blob

var array = new Uint8Array([0x04, 0x06, 0x07, 0x08]);

var blob = new Blob([array]);

Manipulation d'ArrayBuffers avec DataViews

DataViews fournit des méthodes pour lire et écrire des valeurs individuelles à partir d'un ArrayBuffer, au lieu de les afficher en tant que tableau d'un seul type. Nous définissons ici deux octets individuellement, puis nous les interprétons ensemble sous la forme d'un entier non signé de 16 bits, le premier étant le big-endian puis le little-endian.

var buffer = new ArrayBuffer(2);
var view = new DataView(buffer);

view.setUint8(0, 0xFF);
view.setUint8(1, 0x01);

console.log(view.getUint16(0, false)); // 65281
console.log(view.getUint16(0, true));  // 511

Création d'un objet TypedArray à partir d'une chaîne Base64

var data = 
   'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACN' +
   'byblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHx' +
   'gljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

var characters = atob(data);

var array = new Uint8Array(characters.length);

for (var i = 0; i < characters.length; i++) {
  array[i] = characters.charCodeAt(i);
}

Utiliser TypedArrays

TypedArrays est un ensemble de types fournissant différentes vues dans des ArrayBuffers binaires de longueur fixe. Pour la plupart, ils agissent comme des tableaux contraignant toutes les valeurs affectées à un type numérique donné. Vous pouvez transmettre une instance ArrayBuffer à un constructeur TypedArray pour créer une nouvelle vue de ses données.

var buffer = new ArrayBuffer(8);
var byteView = new Uint8Array(buffer);
var floatView = new Float64Array(buffer);

console.log(byteView);  // [0, 0, 0, 0, 0, 0, 0, 0]
console.log(floatView); // [0]
byteView[0] = 0x01;
byteView[1] = 0x02;
byteView[2] = 0x04;
byteView[3] = 0x08;
console.log(floatView); // [6.64421383e-316]

ArrayBuffers peut être copié à l'aide de la .slice(...) , directement ou via une vue TypedArray.

var byteView2 = byteView.slice();
var floatView2 = new Float64Array(byteView2.buffer);
byteView2[6] = 0xFF;
console.log(floatView);  // [6.64421383e-316]
console.log(floatView2); // [7.06327456e-304]

Obtenir une représentation binaire d'un fichier image

Cet exemple est inspiré par cette question .

Nous supposerons que vous savez comment charger un fichier à l'aide de l'API de fichier .

// preliminary code to handle getting local file and finally printing to console
// the results of our function ArrayBufferToBinary().
var file = // get handle to local file.
var reader = new FileReader();
reader.onload = function(event) {
    var data = event.target.result;
    console.log(ArrayBufferToBinary(data));
};
reader.readAsArrayBuffer(file); //gets an ArrayBuffer of the file

Maintenant, nous effectuons la conversion réelle des données de fichier en 1 et 0 à l'aide d'un DataView :

function ArrayBufferToBinary(buffer) {
   // Convert an array buffer to a string bit-representation: 0 1 1 0 0 0...
   var dataView = new DataView(buffer);
   var response = "", offset = (8/8); 
   for(var i = 0; i < dataView.byteLength; i += offset) {
       response += dataView.getInt8(i).toString(2); 
   }
   return response;
}

DataView vous permet de lire / écrire des données numériques; getInt8 convertit les données de la position d'octet - ici 0 , la valeur passée - dans ArrayBuffer en une représentation d'entier 8 bits signée, et toString(2) convertit l'entier 8 bits en format de représentation binaire (une chaîne de 1 et 0).

Les fichiers sont enregistrés en tant qu'octets. La valeur de décalage «magique» est obtenue en notant que nous prenons des fichiers stockés sous forme d’octets, c’est-à-dire des entiers de 8 bits, et que nous les lisons dans une représentation entière de 8 bits. Si nous essayions de lire nos fichiers sauvegardés en octets (c.-à-d. 8 bits) sur des entiers de 32 bits, notons que 32/8 = 4 est le nombre d'espaces d'octets, qui est notre valeur de décalage d'octet.


Pour cette tâche, DataView est excessif. Ils sont généralement utilisés dans les cas où des données endianness ou hétérogènes sont rencontrées (par exemple, lors de la lecture de fichiers PDF, dont les en-têtes sont encodés dans des bases différentes et que nous souhaitons extraire cette valeur de manière significative). Parce que nous voulons juste une représentation textuelle, nous ne nous soucions pas de l’hétérogénéité car il n’ya jamais besoin de

Une solution bien meilleure - et plus courte - peut être trouvée en utilisant un UInt8Array typé UInt8Array , qui traite l'ensemble du ArrayBuffer comme composé d'entiers non signés de 8 bits:

function ArrayBufferToBinary(buffer) {
    var uint8 = new Uint8Array(buffer);
    return uint8.reduce((binary, uint8) => binary + uint8.toString(2), "");
}

Itérer via un arrayBuffer

Pour un moyen pratique de parcourir un arrayBuffer, vous pouvez créer un itérateur simple qui implémente les méthodes DataView sous le capot:

var ArrayBufferCursor = function() {
  var ArrayBufferCursor = function(arrayBuffer) {
    this.dataview = new DataView(arrayBuffer, 0);
    this.size = arrayBuffer.byteLength;
    this.index = 0;
  }

  ArrayBufferCursor.prototype.next = function(type) {
    switch(type) {
      case 'Uint8':
        var result = this.dataview.getUint8(this.index);
        this.index += 1;
        return result;
      case 'Int16':
        var result = this.dataview.getInt16(this.index, true);
        this.index += 2;
        return result;
      case 'Uint16':
        var result = this.dataview.getUint16(this.index, true);
        this.index += 2;
        return result;
      case 'Int32':
        var result = this.dataview.getInt32(this.index, true);
        this.index += 4;
        return result;
      case 'Uint32':
        var result = this.dataview.getUint32(this.index, true);
        this.index += 4;
        return result;
      case 'Float':
      case 'Float32':
        var result = this.dataview.getFloat32(this.index, true);
        this.index += 4;
        return result;
      case 'Double':
      case 'Float64':
        var result = this.dataview.getFloat64(this.index, true);
        this.index += 8;
        return result;
      default:
        throw new Error("Unknown datatype");
    }
  };

  ArrayBufferCursor.prototype.hasNext = function() {
    return this.index < this.size;
  }

  return ArrayBufferCursor;
});

Vous pouvez ensuite créer un itérateur comme ceci:

var cursor = new ArrayBufferCursor(arrayBuffer);

Vous pouvez utiliser le hasNext pour vérifier s'il y a encore des éléments

for(;cursor.hasNext();) {
    // There's still items to process
}

Vous pouvez utiliser la méthode next pour prendre la valeur suivante:

var nextValue = cursor.next('Float');

Avec un tel itérateur, écrire votre propre analyseur pour traiter les données binaires devient assez facile.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow