`DataView` in JavaScript
This article explains DataView
in JavaScript.
We will explain in detail the basic usage of DataView
and specific examples of its use.
YouTube Video
DataView
in JavaScript
JavaScript's DataView
is a convenient API for manipulating data stored in a buffer (ArrayBuffer
) in various formats. This allows for flexible and efficient reading and writing of binary data, playing an important role in network communication, file processing, and interfacing with WebAssembly.
What is DataView
?
DataView
provides a view layer over an ArrayBuffer
object, allowing you to read and write different data types (such as integers, floating-point numbers, and characters) from any byte offset. DataView
is similar to TypedArray
, but it is characterized by its ability to specify endianness and perform detailed operations on a byte level.
Basic Syntax of DataView
1let buffer = new ArrayBuffer(16); // Create a 16-byte ArrayBuffer
2let view = new DataView(buffer); // Manipulate the buffer with a DataView
DataView
has a constructor that takes an ArrayBuffer
as an argument. In this example, a 16-byte buffer is created, and DataView
is used to access that buffer. Using DataView
, you can specify different byte sizes and endianness (big-endian or little-endian) when reading from or writing to data stored in a buffer.
Basic Methods of DataView
DataView
provides methods for reading and writing values of various data types. They are mainly divided into get
methods for data reading and set
methods for writing.
The main methods are shown below.
Methods for Reading Values
getInt8(byteOffset)
: Reads a 1-byte signed integer at the specified offset.getUint8(byteOffset)
: Reads a 1-byte unsigned integer at the specified offset.getInt16(byteOffset, littleEndian)
: Reads a 2-byte signed integer.getUint16(byteOffset, littleEndian)
: Reads a 2-byte unsigned integer.getInt32(byteOffset, littleEndian)
: Reads a 4-byte signed integer.getUint32(byteOffset, littleEndian)
: Reads a 4-byte unsigned integer.getFloat32(byteOffset, littleEndian)
: Reads a 4-byte IEEE 754 floating-point number.getFloat64(byteOffset, littleEndian)
: Reads an 8-byte IEEE 754 floating-point number.
Methods for Writing Values
setInt8(byteOffset, value)
: Writes a 1-byte signed integer.setUint8(byteOffset, value)
: Writes a 1-byte unsigned integer.setInt16(byteOffset, value, littleEndian)
: Writes a 2-byte signed integer.setUint16(byteOffset, value, littleEndian)
: Writes a 2-byte unsigned integer.setInt32(byteOffset, value, littleEndian)
: Writes a 4-byte signed integer.setUint32(byteOffset, value, littleEndian)
: Writes a 4-byte unsigned integer.setFloat32(byteOffset, value, littleEndian)
: Writes a 4-byte IEEE 754 floating-point number.setFloat64(byteOffset, value, littleEndian)
: Writes an 8-byte IEEE 754 floating-point number.
By using these methods, you can flexibly read and write data stored in an ArrayBuffer
.
Example of using DataView
Let's look at an example of manipulating binary data using DataView
.
Example 1: Writing and reading a 16-bit integer
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
- In this example, the
setInt16
method is used to write a 16-bit signed integer in little-endian format, and thegetInt16
method reads that value in little-endian.
Example 2: Writing and reading a floating point number
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
- In this example, the
setFloat64
method is used to write a 64-bit floating-point number in big-endian format, and that value is read withgetFloat64
.
About Endianness
Let's see an example of reading and writing values in both big-endian and little-endian formats using 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));
In DataView
methods, data is stored in big-endian (byte order from most significant to least significant byte) by default, but little-endian can be specified optionally. Little-endian reverses the byte order (from least significant to most significant byte). It is important to handle data endianness correctly because different systems and network protocols use different endianness.
Difference from TypedArray
Let's look at the differences between DataView
and 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
also provides buffer operations based on ArrayBuffer
, but TypedArray
is suitable for operating on contiguous data with a fixed length and format for each data type. On the other hand, DataView
can flexibly operate on different data types and also allows control over endianness. Therefore, DataView
is suitable for parsing and constructing complex binary data.
Summary
DataView
is a powerful API for handling binary data in JavaScript. You can directly access ArrayBuffer
to read and write data while considering integers, floating-point numbers, and differences in endianness. It is useful in situations like network communication and file format parsing, and is indispensable when byte-level control is required. By using it together with TypedArray
, you can perform more efficient binary data manipulation.
You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.