Comprensione dei buffer in Node.js
Un buffer è una posizione specifica nella memoria non elaborata. Serve come spazio di archiviazione temporaneo per i dati binari in eccesso che l’unità di elaborazione non può accettare in quel particolare momento.
Node.js include una classe Buffer. Può gestire dati binari durante la gestione di flussi TCP (Transfer Control Protocol) e operazioni di lettura-scrittura su un file system.
Scopri come creare, leggere e modificare il contenuto di un buffer.
Creazione di un buffer
Per creare un Buffer in Node.js, utilizzerai i metodi alloc() o from() . Il metodo alloc() crea un nuovo buffer, specificandone la dimensione durante la creazione come primo e unico parametro richiesto. È utile quando non si hanno dati da archiviare al momento della creazione del buffer.
Specificare il parametro della dimensione del buffer in byte quando si crea un buffer con il metodo alloc() . Per esempio:
const buf = Buffer.alloc(8);
console.log(buf);
// output: <Buffer 00 00 00 00 00 00 00 00>
La classe Buffer aggiunge automaticamente zeri come valori segnaposto per i nuovi dati quando li crei con il metodo alloc() .
La classe Buffer esprime ogni valore 0 come 00 , utilizzando il formato esadecimale. In questo esempio, contiene un totale di otto valori.
Per inizializzare il Buffer con valori segnaposto diversi, passare un secondo parametro di riempimento :
const buf_filled = Buffer.alloc(8, 5);
console.log(buf_filled);
// output: <Buffer 05 05 05 05 05 05 05 05>
Questo oggetto cita una porzione di memoria che memorizza 8 byte del valore 05 . Si noti che sebbene sia stato passato un numero come parametro di riempimento , i buffer memorizzano solo i dati in formato binario.
Dopo aver allocato la memoria nel Buffer, scrivi i dati chiamando il metodo write() :
const buf = Buffer.alloc(8);
buf.write("v", "utf-8");
console.log(buf)
// output: <Buffer 76 00 00 00 00 00 00 00>
buf.write("va","utf-8");
console.log(buf)
// output: <Buffer 76 61 00 00 00 00 00 00>
Il metodo write() usa la codifica dei caratteri per convertire il primo parametro, usando utf-8 e poi scrive la stringa nel Buffer. L’aggiunta di un secondo carattere alla stringa riempirà il secondo byte.
Per estrarre dati da tipi di dati esistenti come stringhe o array, utilizzare il metodo from() . Questo metodo crea buffer da stringhe e matrici.
Per esempio:
// String
const stringBuf = Buffer.from('string')
console.log(stringBuf)
// output: <Buffer 73 74 72 69 6e 67>
// Array
const arrayBuf = Buffer.from([97, 114, 114, 97, 121], 'hex')
console.log(arrayBuf);
// output: <Buffer 61 72 72 61 79>
Il metodo from() accetta l’input come primo parametro, calcola il numero di byte necessari per codificare i dati e quindi invia il risultato al Buffer. Fornendo un altro formato di codifica come secondo parametro, è possibile ignorare la codifica predefinita (UTF-8).
Il passaggio di numeri al metodo from() genererà un errore.
Lettura di un buffer
Sebbene i buffer siano simili agli array, non sono ridimensionabili e possono gestire i dati binari del computer grazie ai metodi incorporati.
La classe Buffer ci consente di leggere singoli byte dei suoi dati utilizzando la sintassi delle parentesi quadre di JavaScript.
Per esempio:
const myBuf = Buffer.from('Mine');
console.log(MyBuf[1]);
// output: 105
console.log(MyBuf[3]);
// output: 101
console.log(MyBuf[5]);
// output: undefined
Il blocco di codice sopra utilizza la sintassi della parentesi quadra per ottenere i valori del primo e del terzo byte nella loro rappresentazione decimale. Il tentativo di ottenere un byte non valido comporterà un errore indefinito .
Per accedere a tutti i suoi dati, la classe Buffer viene fornita con i metodi toJSON() e toString() , che ottengono i contenuti in due diversi formati.
Il metodo toString() emette una stringa come contenuto del buffer:
const myBuf = Buffer.from('Mine');
console.log(myBuf.toString());
// output: 'Mine'
const numberBuf = Buffer.from([123]);
console.log(numberBuf.toString())
// output: '{'
const emptyBuf = Buffer.alloc(5);
console.log(emptyBuf.toString());
// output: '\\x00\\x00\\x00\\x00\\x00'
La prima chiamata inizializza il Buffer con il valore ” Mine “, che viene replicato dalla chiamata a toString. Il secondo esempio utilizza un array single-int per l’inizializzazione, che ha una rappresentazione di stringa come il carattere ” { “. Nel caso finale, un Buffer con cinque valori null restituisce la stringa “ \x00\x00\x00\x00\x00 ”. La stringa \x00 è la rappresentazione esadecimale di null.
Il metodo .toJSON() restituisce la rappresentazione decimale dei dati Buffer, indipendentemente dai dati utilizzati per inizializzare il Buffer.
Per esempio:
const myBuf = Buffer.from('Mine');
console.log(myBuf.toJSON());
// output: { type: 'Buffer', data: [ 77, 105, 110, 101 ] }
L’output JSON ha una proprietà type con un valore Buffer per indicarne l’origine. La sua proprietà data memorizza un array di decimali che rappresentano l’array di byte originale.
Modifica di un buffer
Analogamente all’accesso ai singoli byte di un Buffer, è anche possibile modificare i singoli byte del contenuto di un Buffer utilizzando la sintassi delle parentesi quadre.
Quando si utilizza la sintassi delle parentesi quadre per modificare un singolo contenuto, è possibile assegnare solo la rappresentazione decimale del valore.
Per esempio:
myBuf[0] = 70
console.log(myBuf.toString())
// output: 'Fine'
Poiché i buffer sono dati binari, non è possibile assegnare una stringa a una parte specifica di un buffer. Se provi a impostare un singolo byte su una stringa, Buffer lo tradurrà in un carattere nullo.
Per esempio:
myBuf[0] = 'F';
console.log(myBuf.toString());
// output: '\\x00ine'
In alternativa, puoi modificare l’intero contenuto di un buffer utilizzando il metodo write() .
Prendi in considerazione l’inserimento di un indice al di fuori della lunghezza del Buffer. Anziché restituire un errore, Buffer ignora l’indice non valido e mantiene intatto il contenuto originale di Buffer.
Ad esempio, prova a impostare il quinto elemento di myBuf su r tramite la sua rappresentazione decimale di 114 :
myBuf[4] = 114;
console.log(myBuf.toString());
// output: 'Mine'
Si noti che il metodo toString() restituisce lo stesso valore ‘Mine’ .
Dal momento che non è possibile ridimensionare un buffer, il tentativo di scrivere più dati di quelli che si possono contenere comporterà l’eliminazione dei dati extra. Per esempio:
const buf1 = Buffer.alloc(5)
buf1.write('number');
console.log(buf1.toString())
// output: 'numbe'
Utilizzando il metodo toString() per confermare i dati del buffer, restituisce ‘numbe’ anziché ‘number’. Qual è l’argomento inserito all’interno del metodo write() .
I buffer scrivono in modo seriale a partire dall’indice zero. Il metodo write() aggiunge serialmente byte a un Buffer, sovrascrivendo qualsiasi dato precedente.
Per esempio:
const buf2 = Buffer.alloc(6);
buf2.write('member');
console.log(buf2.toString())
// output: 'member'
buf2.write('hi');
console.log(buf2.toString());
// output: 'himber'
Il codice precedente crea un buffer di sei byte e vi aggiunge la stringa ” member” utilizzando il metodo write() .
Quindi aggiorna il buffer con il nuovo contenuto che occupa meno spazio di memoria rispetto al contenuto precedente.
Ciò comporta la creazione di una nuova stringa con i primi due byte sovrascritti e i restanti byte lasciati inalterati.
Molte API e strutture dati utilizzano i buffer
Ora sai come creare un buffer, scriverne uno, leggerne il contenuto e modificarlo con i metodi appropriati.
Sono disponibili molti altri metodi per lavorare con la classe Node.js Buffer.
Dovresti conoscere questi metodi e comprendere i buffer per capire come funzionano concetti diversi come flussi e file system.
Lascia un commento