`DataView` in JavaScript

`DataView` in JavaScript

Questo articolo spiega DataView in JavaScript.

Spiegheremo in dettaglio l'uso basilare di DataView e esempi specifici del suo utilizzo.

YouTube Video

DataView in JavaScript

Il DataView di JavaScript è un'API conveniente per manipolare i dati memorizzati in un buffer (ArrayBuffer) in vari formati. Ciò consente una lettura e scrittura flessibili ed efficienti di dati binari, svolgendo un ruolo importante nella comunicazione di rete, nell'elaborazione dei file e nell'interfaccia con WebAssembly.

Che cos'è DataView?

DataView fornisce un livello di visualizzazione sopra un oggetto ArrayBuffer, consentendoti di leggere e scrivere diversi tipi di dati (come interi, numeri in virgola mobile e caratteri) da qualsiasi offset di byte. DataView è simile a TypedArray, ma si distingue per la capacità di specificare l'endianness e di effettuare operazioni dettagliate a livello di byte.

Sintassi Base di DataView

1let buffer = new ArrayBuffer(16);  // Create a 16-byte ArrayBuffer
2let view = new DataView(buffer);    // Manipulate the buffer with a DataView

DataView ha un costruttore che accetta un ArrayBuffer come argomento. In questo esempio viene creato un buffer da 16 byte e DataView viene utilizzato per accedere a quel buffer. Utilizzando DataView, puoi specificare diverse dimensioni di byte e l'endianness (big-endian o little-endian) durante la lettura o scrittura di dati memorizzati in un buffer.

Metodi Base di DataView

DataView fornisce metodi per leggere e scrivere valori di vari tipi di dati. Sono principalmente suddivisi in metodi get per la lettura dei dati e metodi set per la scrittura.

I metodi principali sono mostrati di seguito.

Metodi per la Lettura dei Valori

  • getInt8(byteOffset): Legge un intero con segno a 1 byte all'offset specificato.
  • getUint8(byteOffset): Legge un intero senza segno a 1 byte all'offset specificato.
  • getInt16(byteOffset, littleEndian): Legge un intero con segno a 2 byte.
  • getUint16(byteOffset, littleEndian): Legge un intero senza segno a 2 byte.
  • getInt32(byteOffset, littleEndian): Legge un intero con segno a 4 byte.
  • getUint32(byteOffset, littleEndian): Legge un intero senza segno a 4 byte.
  • getFloat32(byteOffset, littleEndian): Legge un numero in virgola mobile IEEE 754 a 4 byte.
  • getFloat64(byteOffset, littleEndian): Legge un numero in virgola mobile IEEE 754 a 8 byte.

Metodi per Scrivere Valori

  • setInt8(byteOffset, value): Scrive un intero con segno a 1 byte.
  • setUint8(byteOffset, value): Scrive un intero senza segno a 1 byte.
  • setInt16(byteOffset, value, littleEndian): Scrive un intero con segno a 2 byte.
  • setUint16(byteOffset, value, littleEndian): Scrive un intero senza segno a 2 byte.
  • setInt32(byteOffset, value, littleEndian): Scrive un intero con segno a 4 byte.
  • setUint32(byteOffset, value, littleEndian): Scrive un intero senza segno a 4 byte.
  • setFloat32(byteOffset, value, littleEndian): Scrive un numero in virgola mobile IEEE 754 a 4 byte.
  • setFloat64(byteOffset, value, littleEndian): Scrive un numero in virgola mobile IEEE 754 a 8 byte.

Utilizzando questi metodi, è possibile leggere e scrivere in modo flessibile i dati archiviati in un ArrayBuffer.

Esempio di utilizzo di DataView

Vediamo un esempio di manipolazione di dati binari utilizzando DataView.

Esempio 1: Scrittura e lettura di un intero a 16 bit

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 questo esempio, il metodo setInt16 viene utilizzato per scrivere un intero con segno a 16 bit in formato little-endian, e il metodo getInt16 legge quel valore in little-endian.

Esempio 2: Scrittura e lettura di un numero in virgola mobile

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 questo esempio, il metodo setFloat64 viene utilizzato per scrivere un numero in virgola mobile a 64 bit in formato big-endian, e quel valore viene letto con getFloat64.

Informazioni sulla Endianness

Vediamo un esempio di lettura e scrittura di valori in formato big-endian e little-endian utilizzando 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));

Nei metodi di DataView, i dati sono archiviati in formato big-endian (ordine dei byte dal più significativo al meno significativo) per impostazione predefinita, ma è possibile specificare opzionalmente il formato little-endian. Il formato little-endian inverte l'ordine dei byte (dal meno significativo al più significativo). È importante gestire correttamente l'endianness dei dati perché diversi sistemi e protocolli di rete usano tipi di endianness differenti.

Differenza rispetto a TypedArray

Vediamo le differenze tra DataView e 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 fornisce anch'esso operazioni sui buffer basate su ArrayBuffer, ma è adatto per operare su dati contigui con una lunghezza e un formato fisso per ciascun tipo di dato. D'altra parte, DataView può operare in modo flessibile su tipi di dati diversi e consente anche il controllo sull'endianness. Pertanto, DataView è adatto per analizzare e costruire dati binari complessi.

Riepilogo

DataView è un'API potente per gestire i dati binari in JavaScript. È possibile accedere direttamente a ArrayBuffer per leggere e scrivere dati tenendo conto di numeri interi, numeri con virgola mobile e differenze di endianness. È utile in situazioni come la comunicazione in rete e l'analisi di formati di file ed è indispensabile quando è richiesto un controllo a livello di byte. Utilizzandolo insieme a TypedArray, puoi eseguire una manipolazione dei dati binari più efficiente.

Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.

YouTube Video