`DataView` i JavaScript

`DataView` i JavaScript

Denne artikel forklarer DataView i JavaScript.

Vi vil forklare i detaljer den grundlæggende brug af DataView og konkrete eksempler på dets anvendelse.

YouTube Video

DataView i JavaScript

DataView i JavaScript er et praktisk API til at manipulere data, der er lagret i en buffer (ArrayBuffer), i forskellige formater. Dette muliggør fleksibel og effektiv læsning og skrivning af binære data og spiller en vigtig rolle i netværkskommunikation, filbehandling og interaktion med WebAssembly.

Hvad er DataView?

DataView giver et visningslag over et ArrayBuffer-objekt og tillader læsning og skrivning af forskellige datatyper (såsom heltal, flydetal og tegn) fra enhver byteoffset. DataView ligner TypedArray, men er kendetegnet ved sin evne til at specificere byte-orden (endianness) og udføre detaljerede operationer på byteniveau.

Grundlæggende syntaks for DataView

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

DataView har en konstruktør, der tager en ArrayBuffer som argument. I dette eksempel oprettes en 16-byte buffer, og DataView bruges til at få adgang til denne buffer. Ved hjælp af DataView kan du specificere forskellige byte-størrelser og endianness (big-endian eller little-endian), når du læser fra eller skriver til data, der er lagret i en buffer.

Grundlæggende metoder for DataView

DataView tilbyder metoder til at læse og skrive værdier af forskellige datatyper. De er hovedsageligt opdelt i get-metoder til at læse data og set-metoder til at skrive.

De vigtigste metoder er vist nedenfor.

Metoder til læsning af værdier

  • getInt8(byteOffset): Læser et 1-byte underskrevet heltal ved den angivne offset.
  • getUint8(byteOffset): Læser et 1-byte usigneret heltal ved den angivne offset.
  • getInt16(byteOffset, littleEndian): Læser et 2-byte underskrevet heltal.
  • getUint16(byteOffset, littleEndian): Læser et 2-byte usigneret heltal.
  • getInt32(byteOffset, littleEndian): Læser et 4-byte underskrevet heltal.
  • getUint32(byteOffset, littleEndian): Læser et 4-byte usigneret heltal.
  • getFloat32(byteOffset, littleEndian): Læser et 4-byte IEEE 754 flydetal.
  • getFloat64(byteOffset, littleEndian): Læser et 8-byte IEEE 754 flydende punkt tal.

Metoder til skriving af værdier

  • setInt8(byteOffset, value): Skriver et 1-byte fortegnstal.
  • setUint8(byteOffset, value): Skriver et 1-byte ufortegnstal.
  • setInt16(byteOffset, value, littleEndian): Skriver et 2-byte fortegnstal.
  • setUint16(byteOffset, value, littleEndian): Skriver et 2-byte ufortegnstal.
  • setInt32(byteOffset, value, littleEndian): Skriver et 4-byte fortegnstal.
  • setUint32(byteOffset, value, littleEndian): Skriver et 4-byte ufortegnstal.
  • setFloat32(byteOffset, value, littleEndian): Skriver et 4-byte IEEE 754 flydende punkt tal.
  • setFloat64(byteOffset, value, littleEndian): Skriver et 8-byte IEEE 754 flydende punkt tal.

Ved at bruge disse metoder kan du fleksibelt læse og skrive data, der er lagret i en ArrayBuffer.

Eksempel på brug af DataView

Lad os se et eksempel på at manipulere binære data ved hjælp af DataView.

Eksempel 1: Skrive og læse en 16-bit heltalsværdi

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
  • I dette eksempel bruges setInt16 metoden til at skrive et 16-bit fortegnstal i little-endian format, og getInt16 metoden læser denne værdi i little-endian.

Eksempel 2: Skrive og læse et flydende punkt tal

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
  • I dette eksempel bruges setFloat64 metoden til at skrive et 64-bit flydende punkt tal i big-endian format, og denne værdi læses med getFloat64.

Om byte-rækkefølge (Endianness)

Lad os se et eksempel på at læse og skrive værdier i både big-endian og little-endian formater ved hjælp af 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));

I DataView metoder gemmes data som standard i big-endian (byte rækkefølge fra mest signifikante til mindst signifikante byte), men little-endian kan angives som en mulighed. Little-endian vender byte-rækkefølgen om (fra mindst signifikante til mest signifikante byte). Det er vigtigt at håndtere datas endianness korrekt, fordi forskellige systemer og netværksprotokoller anvender forskellige endianness.

Forskel fra TypedArray

Lad os se på forskellene mellem DataView og 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 giver også bufferoperationer baseret på ArrayBuffer, men TypedArray er egnet til at arbejde med sammenhængende data med fast længde og format for hver datatype. På den anden side kan DataView fleksibelt arbejde med forskellige datatyper og giver også mulighed for at kontrollere byte-rækkefølgen (endianness). Derfor er DataView egnet til at analysere og konstruere komplekse binære data.

Sammendrag

DataView er en kraftfuld API til håndtering af binære data i JavaScript. Du kan få direkte adgang til ArrayBuffer for at læse og skrive data, mens du tager højde for heltal, flydende komma-tal og forskelle i endianness. Det er nyttigt i situationer som netværkskommunikation og filformatparsing og er uundværligt, når kontrol på byte-niveau er påkrævet. Ved at bruge det sammen med TypedArray kan du udføre mere effektiv manipulation af binære data.

Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.

YouTube Video