수색…
비고
Typed Arrays는 원래 Khronos 편집자의 초안에 의해 지정 되었고 나중에 ECMAScript 6 § 24 및 § 22.2 에서 표준화되었습니다.
BLOB는 W3C File API 작업 초안에 의해 지정 됩니다 .
Blob과 ArrayBuffers 간의 변환
자바 스크립트는 브라우저에서 바이너리 데이터를 나타내는 두 가지 기본 방법이 있습니다. ArrayBuffers / TypedArrays에는 직접 조작 할 수있는 가변 길이 (여전히 고정 길이이지만) 바이너리 데이터가 들어 있습니다. BLOB에는 비동기 File 인터페이스를 통해서만 액세스 할 수있는 불변의 바이너리 데이터가 포함되어 있습니다.
Blob
을 ArrayBuffer
변환 (비동기식)
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);
Promise
(비동기)를 사용하여 Blob
을 ArrayBuffer
변환
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');
이러한 반복기를 사용하면 바이너리 데이터를 처리하기 위해 자체 파서를 작성하는 것이 매우 쉽습니다.