JavaScript의 `DataView`
이 문서는 JavaScript의 DataView
를 설명합니다.
DataView
의 기본 사용법과 구체적인 사용 사례에 대해 자세히 설명하겠습니다.
YouTube Video
JavaScript의 DataView
JavaScript의 DataView
는 버퍼(ArrayBuffer
)에 저장된 데이터를 다양한 형식으로 조작할 수 있는 편리한 API입니다. 이를 통해 이진 데이터를 유연하고 효율적으로 읽고 쓸 수 있으며, 네트워크 통신, 파일 처리 및 WebAssembly와의 인터페이스에서 중요한 역할을 합니다.
DataView
란 무엇인가요?
DataView
는 ArrayBuffer
객체 위에 보기 레이어(view layer)를 제공하여 정수, 부동소수점, 문자 등 다양한 데이터 타입을 임의의 바이트 오프셋에서 읽고 쓸 수 있게 합니다. DataView
는 TypedArray
와 유사하지만, 엔디언(바이트 순서)을 지정하고 바이트 단위의 세부적인 작업을 수행할 수 있다는 점에서 차별화됩니다.
DataView
의 기본 구문
1let buffer = new ArrayBuffer(16); // Create a 16-byte ArrayBuffer
2let view = new DataView(buffer); // Manipulate the buffer with a DataView
DataView
는 ArrayBuffer
를 인수로 받는 생성자를 가집니다. 이 예제에서는 16바이트 버퍼를 생성하고, DataView
를 사용하여 해당 버퍼에 접근합니다. DataView
를 사용하면, 버퍼에 저장된 데이터를 읽거나 쓸 때 바이트 크기와 엔디언(big-endian 혹은 little-endian)을 지정할 수 있습니다.
DataView
의 기본 메서드
DataView
는 다양한 데이터 타입의 값을 읽고 쓰는 메서드를 제공합니다. 이들은 주로 데이터를 읽는 get
메서드와 쓰는 set
메서드로 나뉩니다.
주요 메서드는 아래와 같습니다.
값을 읽는 메서드
getInt8(byteOffset)
: 지정된 오프셋에서 1바이트 부호 있는 정수를 읽습니다.getUint8(byteOffset)
: 지정된 오프셋에서 1바이트 부호 없는 정수를 읽습니다.getInt16(byteOffset, littleEndian)
: 2바이트 부호 있는 정수를 읽습니다.getUint16(byteOffset, littleEndian)
: 2바이트 부호 없는 정수를 읽습니다.getInt32(byteOffset, littleEndian)
: 4바이트 부호 있는 정수를 읽습니다.getUint32(byteOffset, littleEndian)
: 4바이트 부호 없는 정수를 읽습니다.getFloat32(byteOffset, littleEndian)
: 4바이트 IEEE 754 부동소수점 숫자를 읽습니다.getFloat64(byteOffset, littleEndian)
: 8바이트 IEEE 754 부동소수점 숫자를 읽습니다.
값을 쓰기 위한 메서드들
setInt8(byteOffset, value)
: 1바이트 부호 있는 정수를 씁니다.setUint8(byteOffset, value)
: 1바이트 부호 없는 정수를 씁니다.setInt16(byteOffset, value, littleEndian)
: 2바이트 부호 있는 정수를 씁니다.setUint16(byteOffset, value, littleEndian)
: 2바이트 부호 없는 정수를 씁니다.setInt32(byteOffset, value, littleEndian)
: 4바이트 부호 있는 정수를 씁니다.setUint32(byteOffset, value, littleEndian)
: 4바이트 부호 없는 정수를 씁니다.setFloat32(byteOffset, value, littleEndian)
: 4바이트 IEEE 754 부동소수점 숫자를 씁니다.setFloat64(byteOffset, value, littleEndian)
: 8바이트 IEEE 754 부동소수점 숫자를 씁니다.
이 메서드들을 사용하여 ArrayBuffer
에 저장된 데이터를 유연하게 읽고 쓸 수 있습니다.
DataView
사용 예시
DataView
를 사용하여 이진 데이터를 조작하는 예제를 살펴봅시다.
예제 1: 16비트 정수 쓰기와 읽기
1let buffer = new ArrayBuffer(4); // Create a 4-byte buffer
2let view = new DataView(buffer);
3
4// Write a 2-byte integer value in little-endian format
5view.setInt16(0, 32767, true); // byteOffset: 0, value: 32767, littleEndian: true
6
7// Read the data in little-endian format
8let value = view.getInt16(0, true);
9console.log(value); // Output: 32767
- 이 예제에서는
setInt16
메서드를 사용해 LITTLE_ENDIAN 형식으로 16비트 부호 있는 정수를 쓰고,getInt16
메서드로 그 값을 읽습니다.
예제 2: 부동소수점 숫자 쓰기와 읽기
1let buffer = new ArrayBuffer(8); // Create an 8-byte buffer
2let view = new DataView(buffer);
3
4// Write an 8-byte floating-point number
5view.setFloat64(0, 3.14159, false); // byteOffset: 0, value: 3.14159, bigEndian: false
6
7// Read the data in big-endian format
8let pi = view.getFloat64(0, false);
9console.log(pi); // Output: 3.14159
- 이 예제에서는
setFloat64
메서드를 사용해 BIG_ENDIAN 형식으로 64비트 부동소수점 숫자를 쓰고,getFloat64
로 그 값을 읽습니다.
엔디언에 대하여
DataView
를 사용하여 빅엔디안과 리틀엔디안 형식 모두에서 값을 읽고 쓰는 예제를 살펴봅시다.
1// Example: Handling Endianness with DataView in TypeScript
2// Create an ArrayBuffer of 4 bytes
3const buffer = new ArrayBuffer(4);
4const view = new DataView(buffer);
5
6// Store the same number (0x12345678) in both endian formats
7// By default, DataView uses big-endian
8view.setUint32(0, 0x12345678); // Big-endian
9console.log("Big-endian (default):");
10console.log(buffer);
11
12// Overwrite the buffer with little-endian
13view.setUint32(0, 0x12345678, true); // Little-endian
14console.log("Little-endian:");
15console.log(buffer);
16
17// Read values back in both endian modes
18const bigEndianValue = view.getUint32(0); // Big-endian read
19const littleEndianValue = view.getUint32(0, true); // Little-endian read
20
21console.log("Read as Big-endian:", bigEndianValue.toString(16));
22console.log("Read as Little-endian:", littleEndianValue.toString(16));
DataView
메서드에서 데이터는 기본적으로 BIG_ENDIAN 형식(가장 중요한 바이트부터 가장 덜 중요한 바이트 순서)으로 저장되지만, LITTLE_ENDIAN이 선택적으로 지정 가능합니다. LITTLE_ENDIAN은 바이트 순서를 반대로 뒤집습니다 (가장 덜 중요한 바이트부터 가장 중요한 바이트로). 서로 다른 시스템과 네트워크 프로토콜이 서로 다른 엔디안 방식을 사용하기 때문에 데이터 엔디안 방식을 올바르게 처리하는 것이 중요합니다.
TypedArray
와의 차이점
DataView
와 TypedArray
의 차이점을 살펴봅시다.
1// Example: TypedArray vs DataView
2
3// Create a 8-byte buffer
4const buffer = new ArrayBuffer(8);
5
6// --- Using TypedArray (Int32Array) ---
7const int32View = new Int32Array(buffer);
8int32View[0] = 42;
9int32View[1] = 100;
10
11console.log("TypedArray (Int32Array):");
12console.log(int32View); // Int32Array [42, 100]
13
14// --- Using DataView ---
15const dataView = new DataView(buffer);
16
17// Write different types of data at arbitrary byte offsets
18dataView.setInt8(0, 65); // 1 byte
19dataView.setUint16(1, 500, true); // 2 bytes, little-endian
20dataView.setFloat32(3, 3.14, true); // 4 bytes, little-endian
21
22console.log("\nDataView:");
23console.log("Int8 at 0:", dataView.getInt8(0)); // 65
24console.log("Uint16 at 1:", dataView.getUint16(1, true)); // 500
25console.log("Float32 at 3:", dataView.getFloat32(3, true)); // 3.14
26
27/*
28Output:
29TypedArray (Int32Array):
30Int32Array [42, 100]
31
32DataView:
33Int8 at 0: 65
34Uint16 at 1: 500
35Float32 at 3: 3.140000104904175
36*/
TypedArray
도 ArrayBuffer
를 기반으로 버퍼 연산을 제공하지만, TypedArray
는 각 데이터 타입의 고정된 길이와 형식을 가진 연속 데이터 조작에 적합합니다. 반면, DataView
는 다양한 데이터 타입을 유연하게 다룰 수 있으며 엔디언스를 제어하는 것도 가능합니다. 따라서 DataView
는 복잡한 바이너리 데이터를 구문 분석하고 구성하는 데 적합합니다.
요약
DataView
는 JavaScript에서 바이너리 데이터를 처리하기 위한 강력한 API입니다. 정수, 부동 소수점 숫자 및 엔디언스 차이를 고려하면서 데이터 읽기 및 쓰기를 위해 ArrayBuffer
에 직접 접근할 수 있습니다. 네트워크 통신 및 파일 형식 구문 분석과 같은 상황에서 유용하며, 바이트 단위 제어가 필요한 경우 필수적입니다. TypedArray
와 함께 사용하면 더 효율적으로 이진 데이터를 조작할 수 있습니다.
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.