Modulo fs di NodeJS

Modulo fs di NodeJS

Il modulo nativo fs di nodeJS abilita l'interazione con il file system. Tutte le operazioni che possiamo fare con il modulo fs possono essere fatte sia in modo sincrono che asincrono.

I metodi asincroni possono essere gestiti con con le callback oppure con le promise (preferibile) utilizzando le sintassi async await.

indice

Lettura Asincrona da un file con readFile

Vediamo come creare un modulo per la lettura di un file in modo asincrono con readFile

app.js

// importiamo il modulo fs
const fs = require('fs');

/* 
   - come primo parametro, passiamo il percorso con il nome del file. In questo caso file1.txt
   - come secondo parametro (opzionale) passiamo la codifica del file, in questo caso utf8
   - come terzo parametro, passiamo la callback.
   Il primo parametro della callback è sempre riservato agli errori,
   quindi scriviamo l'oggetto err, e se non ci sono degli errori i dati del file
*/
fs.readFile('file1.txt', 'utf8' , (err, dati) =>{
    //se ci sono degli errori, solleviamo un eccezzione con throw passando l'oggetto err
    if(err) throw err;
    console.log(dati);
});

Gestione dell'errore con readFile (asincrono)

Possiamo gestire gli errori con readFile usando sia gli eventi che definendo una funzione apposita.
Non è possibile usare try catch perchè opera in modo sincrono.

Facciamo un esempio: Proviamo a leggere da un file non esistente con readFile generando quindi un errore che gestiremo definendo una funzione (esempio readfile-err-fn.js) e un altro che gestiremo con gli eventi (esempio readfile-err-evt.js)

Gestione dell'errore definendo una funzione

readfile-err-fn.js

const fs = require('fs');

fs.readFile('file2.txt', (err, data) => {
    if(err) {
        return handleError(new Error(err));
    }
    console.log(err, data);
});

function handleError(errore) {
    console.log('errore gestito');
};

Spiegazione step by step:

const fs = require('fs');

Importiamo il modulo nativo fs di node

fs.readFile('file2.txt', (err, data) => {

passiamo come primo parametro il file (inesistente) e come secondo parametro la callback di gestione che riceverà come primo parametro l'oggetto err se ci sono errori e come secondo parametro i dati del file se non ci sono errori.

    if(err) {
        return handleError(new Error(err));
    }
    console.log(err, data);
});

se ci sono errori, invochiamo la funzione handleError passando in input una nuova istanza della classe Error. Per uscire dal codice usiamo return;

function handleError(errore) {
    console.log('errore gestito');
};

Per gestire l'errore in modo semplice definiamo una funzione handleError(errore) con un semplice console.log di esempio che indica che l'errore è stato gestito

Gestione dell'errore con un evento

readfile-err-evt.js

const fs = require('fs');
const { EventEmitter } = require('events');
const customEmitter = new EventEmitter();


fs.readFile('file2.txt', (err, data) => {
    if(err) {
        return customEmitter.emit('error',err);
    }
    console.log(err, data);
});

customEmitter.on('error', eventoErrore => console.log('errore gestito'));

Spiegazione step by step:

const fs = require('fs');
const { EventEmitter } = require('events');
const customEmitter = new EventEmitter();

Importiamo il modulo nativo fs di node
Importiamo la classe EventEmitter
Definiamo un'instanza di EventEmitter

fs.readFile('file2.txt', (err, data) => {

passiamo come primo parametro il file (inesistente) e come secondo parametro la callback di gestione che riceverà come primo parametro l'oggetto err se ci sono errori e come secondo parametro i dati del file se non ci sono errori.

    if(err) {
        return customEmitter.emit('error',err);
    }
    console.log(err, data);

se ci sono errori, andiamo a sollevare un evento, mettiamo come nome dell'evento ad esempio error e passiamo come parametro err, per uscire dal codice usiamo return;

customEmitter.on('error', eventoErrore => console.log('errore gestito'));

Definiamo un listener per l'evento error e definiamo la callback di gestione eventoErrore e restituiamo un console.log con il valore errore gestito.

Lettura Asincrona da un file con readFile

In Javascript per risolvere il problema noto come callback hell sono state inventate le promise (ES6).
In node possiamo leggere un file in modo asincrono ed utilizzando le promise con fs.promises.readFile

Nella versione ES6 di Javascript possiamo usare promise then catch

readFile-promise.js

const fs = require('fs');

fs.promises.readFile('file2.txt','utf-8')
.then(dati => console.log(dati))
.catch(errore => console.log(errore));

Spiegazione step by step:

fs.promises.readFile('file2.txt','utf-8')

Passiamo come primo parametro il percorso ed il file, e come secondo parametro la codifica del file.

.then(dati => console.log(dati))

Per gestire la risoluzione della promise usiamo il metodo then che riceverà in input i dati del file.

.catch(errore => console.log(errore));

Per gestire gli errori della promise rigettata, usiamo .catch e definiamo la callback che riceverà in input l'oggetto errore

Nelle versioni successive ad ES6 possiamo usare la sintassi async await

readFile-promise-async.js

const fs = require('fs');

async function leggi(leggiquesto) {
    const dati = await fs.promises.readFile(leggiquesto, 'utf8');
    console.log(dati);
};
leggi('file1.txt').catch(err => console.log(err));
leggi('file2.txt').catch(err => console.log(err));

Spiegazione step by step:

async function leggi(leggiquesto) {

definiamo una funzione asincrona che riceverà il percorso ed il nome del file da cui leggere

const dati = await fs.promises.readFile(leggiquesto, 'utf8');
console.log(dati);

attendere la risoluzione della promise , passiamo come primo parametro il percorso ed il nome del file, il questo caso la variabile leggiquesto e come secondo parametro la codifica utf-8

leggi('file1.txt').catch(err => console.log(err));

Invochiamo la funzione leggi passando in input il percorso ed il nome del file. Per gestire gli eventuali errori usiamo .catch, definamo la callback con l'oggetto err.

Scrivere in un file in modo asincrono con fs.writeFile e fs.promises.writeFile

Per scrivere in un file in modo asincrono il modo più semplice è utilizzare writeFile

writeFile.js

const fs = require('fs');

fs.writeFile('scrivifile.txt','YuppiDoH!', err => {
    if(err) throw err;
    console.log('File scritto correttamente');
});

Spiegazione step by step:

fs.writeFile('scrivifile.txt','YuppiDoH!', err => {

Passiamo come primo parametro il percorso ed il file, e come secondo parametro quello che vogliamo scrivere all'interno del file, come terzo parametro la callback che riceverà l'oggetto err in caso di errore.

    if(err) throw err;
    console.log('File scritto correttamente');

Per gestire il problema usiamo genericamente un if(err) throw err; (soluzione non ottimale)

Utilizzare writeFile con le promises

writeFile-promises.js

const fs = require('fs');

fs.promises.writeFile('scrivifile2.txt','YuppiDoh2!')
.then(()=> console.log('Scrittura avvenuta')) ;

Spiegazione step by step:

fs.promises.writeFile('scrivifile2.txt','YuppiDoh2!')

assiamo come primo parametro il percorso ed il file, e come secondo parametro quello che vogliamo scrivere all'interno del file.

fs.promises.writeFile('scrivifile2.txt','YuppiDoh2!')
.then(()=> console.log('Scrittura avvenuta')) ;

Il metodo then() prende due parametri: il primo parametro è la funzione che verrà eseguita nel caso in cui la promise venga risolta; il secondo parametro è la funzione che verrà eseguita se la promise viene rigettata. In questo caso però ci interessa sono il primo parametro dove vogliamo restituire la dicitura scrittura avvenuta, una volta scritto nel file.

Aggiungere del contenuto ad un file

Tutti i metodi visti fin ora per scrivere all'interno dei file, vanno a cancellare il contenuto ed aggiungere il contenuto descritto all'interno del codice. Se invece volessimo soltanto aggiungere del contenuto al contenuto già esistente possiamo usare appendFile.

Utilizzare appendFile per aggiungere contenuto ad un file

appendFile.js

const fs = require('fs');

fs.appendFile('scrivifile.txt','\n Questo è il contenuto aggiunto!', err => {
    if(err) throw err;
    console.log('Il contenuto è stato aggiunto correttamente');
});

Utilizzare appendFile con le promises

appendFile-promises.js

const fs = require('fs');

fs.promises.appendFile('scrivifile2.txt','\n \n \n YuppiDoh2!')
.then(() => console.log('Contenuto aggiunto correttamente')) ;

Scritto da Donato Pirolo

Ciao, sono Donato, frontend developer con una smisurata passione per la SEO. Creo strumenti ad hoc per aiutare aziende e professionisti ad essere cercati sul web e trovare clienti.

Potrebbero interessarti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Copyright © 2022
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram