수색…


비고

Typed Arrays는 원래 Khronos 편집자의 초안에 의해 지정 되었고 나중에 ECMAScript 6 § 24§ 22.2 에서 표준화되었습니다.

BLOB는 W3C File API 작업 초안에 의해 지정 됩니다 .

Blob과 ArrayBuffers 간의 변환

자바 스크립트는 브라우저에서 바이너리 데이터를 나타내는 두 가지 기본 방법이 있습니다. ArrayBuffers / TypedArrays에는 직접 조작 할 수있는 가변 길이 (여전히 고정 길이이지만) 바이너리 데이터가 들어 있습니다. BLOB에는 비동기 File 인터페이스를 통해서만 액세스 할 수있는 불변의 바이너리 데이터가 포함되어 있습니다.

BlobArrayBuffer 변환 (비동기식)

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

Promise (비동기)를 사용하여 BlobArrayBuffer 변환

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

ArrayBuffer 또는 형식화 된 배열을 Blob 변환

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

var blob = new Blob([array]);

DataViews로 ArrayBuffers 조작

DataView는 전체를 단일 유형의 배열로 보는 대신 ArrayBuffer에서 개별 값을 읽고 쓰는 메서드를 제공합니다. 여기에서는 2 바이트를 개별적으로 설정 한 다음 16 비트 부호없는 정수로 첫 번째 빅 엔디안, 리틀 엔디안으로 해석합니다.

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

Base64 문자열에서 TypedArray 만들기

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

TypedArrays 사용

TypedArrays는 고정 길이 가변 바이너리 ArrayBuffers에 다양한 뷰를 제공하는 유형 세트입니다. 대부분의 경우, 할당 된 모든 값을 주어진 숫자 유형으로 강제 변환하는 배열 과 같은 역할을합니다. ArrayBuffer 인스턴스를 TypedArray 생성자에 전달하여 데이터의 새로운 뷰를 만들 수 있습니다.

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]

ArrayBuffer는 .slice(...) 메서드를 사용하여 직접 또는 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]

이미지 파일의 바이너리 표현 얻기

이 예제는 이 질문에 영감을 받았습니다.

File API를 사용하여 파일로드하는 방법을 알고 있다고 가정합니다.

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

이제 DataView 사용하여 파일 데이터를 1과 0으로 실제 변환합니다.

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 하면 숫자 데이터를 읽고 쓸 수 있습니다. getInt8 은 데이터를 바이트 위치 (여기서는 0 )에서 ArrayBuffer 의 값을 부호있는 8 비트 정수 표현으로 변환하고 toString(2) 는 8 비트 정수를 2 진 표현 형식 (즉 1과 2의 문자열 toString(2) 변환합니다. 0의).

파일은 바이트로 저장됩니다. '매직 (magic)'오프셋 값은 바이트로 저장된 파일을 8 비트 정수로 가져 와서 8 비트 정수 표현으로 읽는 것으로 나타납니다. 우리가 바이트 저장 (즉, 8 비트) 파일을 32 비트 정수로 읽으려고한다면 32/8 = 4가 바이트 공간의 수이며, 이는 바이트 오프셋 값입니다.


이 작업의 경우 DataView 는 과도한 작업입니다. 이들은 일반적으로 엔디안 또는 데이터의 이질성이있는 경우 (예 : 다른 기준으로 인코딩 된 헤더가있는 PDF 파일을 읽을 때 의미있는 추출 값으로 사용하려는 경우)에 사용됩니다. 우리는 텍스트 표현을 원하기 때문에 이질성에 대해서는 신경 쓰지 않습니다.

훨씬 더 좋고 더 짧은 해결책은 UInt8Array 형식화 된 배열을 사용하여 찾을 수 있습니다.이 배열은 전체 ArrayBuffer 를 부호없는 8 비트 정수로 구성하여 처리합니다.

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

arrayBuffer를 통해 반복하기

arrayBuffer를 반복 할 수있는 편리한 방법을 위해 두포의 DataView 메소드를 구현하는 간단한 반복자를 만들 수 있습니다.

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

다음과 같이 iterator를 생성 할 수있다.

var cursor = new ArrayBufferCursor(arrayBuffer);

hasNext 를 사용하여 항목이 있는지 확인할 수 있습니다.

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

next 방법을 사용하여 다음 값을 취할 수 있습니다.

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

이러한 반복기를 사용하면 바이너리 데이터를 처리하기 위해 자체 파서를 작성하는 것이 매우 쉽습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow