Suche…


Bemerkungen

Typisierte Arrays wurden ursprünglich durch den Entwurf eines Khronos-Editors festgelegt und später in ECMAScript 6 §24 und §22.2 standardisiert .

Blobs werden im W3C File API-Arbeitsentwurf angegeben .

Konvertierung zwischen Blobs und ArrayBuffers

JavaScript bietet zwei Hauptmethoden, um binäre Daten im Browser darzustellen. ArrayBuffers / TypedArrays enthalten veränderliche (aber immer noch feste Längen) Binärdaten, die Sie direkt bearbeiten können. Blobs enthalten unveränderliche Binärdaten, auf die nur über die asynchrone Dateischnittstelle zugegriffen werden kann.

Konvertieren eines Blob in einen ArrayBuffer (asynchron)

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

Konvertieren eines Blob in einen ArrayBuffer mit einem Promise (asynchron)

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.");
});

Konvertieren Sie ein ArrayBuffer oder ein typisiertes Array in einen Blob

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

var blob = new Blob([array]);

ArrayBuffers mit DataViews bearbeiten

DataViews bieten Methoden zum Lesen und Schreiben einzelner Werte aus einem ArrayBuffer, anstatt das gesamte Objekt als Array eines einzelnen Typs anzuzeigen. Hier setzen wir zwei Bytes einzeln und interpretieren sie dann gemeinsam als vorzeichenlose 16-Bit-Ganzzahl, zuerst Big-Endian, dann 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

Erstellen eines TypedArray aus einer Base64-Zeichenfolge

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);
}

Verwendung von TypedArrays

TypedArrays sind eine Reihe von Typen, die unterschiedliche Ansichten von veränderbaren binären ArrayBuffers mit fester Länge bieten. Meist handelt es sich dabei um Arrays , die alle einem gegebenen numerischen Typ zugewiesenen Werte erzwingen. Sie können eine ArrayBuffer-Instanz an einen TypedArray-Konstruktor übergeben, um eine neue Ansicht der Daten zu erstellen.

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 können mit der .slice(...) -Methode entweder direkt oder über eine TypedArray-Ansicht kopiert werden.

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]

Binäre Darstellung einer Bilddatei abrufen

Dieses Beispiel ist von dieser Frage inspiriert.

Wir gehen davon aus, dass Sie wissen, wie Sie eine Datei mithilfe der Datei-API laden .

// 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

Jetzt führen wir die eigentliche Konvertierung der DataView und DataView mithilfe einer 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 Sie numerische Daten lesen / schreiben. getInt8 konvertiert die Daten von der Byte-Position - hier 0 , der übergebene Wert - im ArrayBuffer in eine vorzeichenbehaftete 8-Bit-Ganzzahlendarstellung, und toString(2) konvertiert die 8-Bit-Ganzzahl in ein binäres Darstellungsformat (dh eine Zeichenfolge von 1 und 0).

Dateien werden als Bytes gespeichert. Der "magische" Versatzwert wird erhalten, indem wir feststellen, dass Dateien, die als Bytes gespeichert sind, dh als 8-Bit-Ganzzahlen, in 8-Bit-Integer-Darstellung gelesen werden. Wenn wir versuchen würden, unsere byte-gespeicherten Dateien (dh 8 Bits) in 32-Bit-Ganzzahlen zu lesen, würden wir feststellen, dass 32/8 = 4 die Anzahl der Byte-Leerzeichen ist, was unser Byte-Offset-Wert ist.


Für diese Aufgabe sind DataView s übertrieben. Sie werden in der Regel in Fällen verwendet, in denen Endianness oder Heterogenität von Daten auftreten (z. B. beim Lesen von PDF-Dateien, deren Header in verschiedenen Basen codiert sind und wir diesen Wert sinnvoll extrahieren möchten). Da wir nur eine Textdarstellung wünschen, ist uns die Heterogenität nicht wichtig, da dies niemals erforderlich ist

Eine viel bessere und kürzere Lösung kann mit einem Array vom Typ UInt8Array gefunden werden, das den gesamten ArrayBuffer als aus vorzeichenlosen 8-Bit-Ganzzahlen behandelt:

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

Iteration durch einen arrayBuffer

Um einen ArrayBuffer bequem durchlaufen zu können, können Sie einen einfachen Iterator erstellen, der die DataView Methoden unter der Haube implementiert:

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;
});

Sie können dann einen Iterator wie folgt erstellen:

var cursor = new ArrayBufferCursor(arrayBuffer);

Mit hasNext können hasNext prüfen, ob noch Elemente vorhanden sind

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

Sie können die next Methode verwenden, um den nächsten Wert zu übernehmen:

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

Mit einem solchen Iterator wird das Schreiben eines eigenen Parsers zur Verarbeitung binärer Daten ziemlich einfach.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow