Ricerca…


Osservazioni

In Node.js, le operazioni intensive come l'I / O vengono eseguite in modo asincrono , ma hanno una controparte sincrona (es. Esiste un file fs.readFile e la sua controparte è fs.readFileSync ). Poiché il nodo è a thread singolo, è necessario prestare attenzione quando si utilizzano le operazioni sincrone , poiché bloccano l'intero processo.

Se un processo è bloccato da un'operazione sincrona, viene interrotto l'intero ciclo di esecuzione (incluso il ciclo degli eventi). Ciò significa che non verranno eseguiti altri codici asincroni, inclusi eventi e gestori di eventi, e il programma continuerà ad attendere fino al completamento dell'operazione di blocco singolo.

Vi sono usi appropriati sia per le operazioni sincrone che asincrone, ma occorre fare attenzione che vengano utilizzati correttamente.

Scrivere su un file usando writeFile o writeFileSync

var fs = require('fs');

// Save the string "Hello world!" in a file called "hello.txt" in
// the directory "/tmp" using the default encoding (utf8).
// This operation will be completed in background and the callback
// will be called when it is either done or failed.
fs.writeFile('/tmp/hello.txt', 'Hello world!', function(err) {
  // If an error occurred, show it and return
  if(err) return console.error(err);
  // Successfully wrote to the file!
});

// Save binary data to a file called "binary.txt" in the current
// directory. Again, the operation will be completed in background.
var buffer = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6f ]);
fs.writeFile('binary.txt', buffer, function(err) {
  // If an error occurred, show it and return
  if(err) return console.error(err);
  // Successfully wrote binary contents to the file!
});

fs.writeFileSync comporta in modo simile a fs.writeFile , ma non fs.writeFile una richiamata poiché completa in modo sincrono e quindi blocca il thread principale. La maggior parte degli sviluppatori di node.js preferiscono le varianti asincrone che non causeranno praticamente alcun ritardo nell'esecuzione del programma.

Nota: il blocco del thread principale è una pratica scorretta in node.js. La funzione sincrona deve essere utilizzata solo durante il debug o quando non sono disponibili altre opzioni.

// Write a string to another file and set the file mode to 0755
try {
  fs.writeFileSync('sync.txt', 'anni', { mode: 0o755 });
} catch(err) {
  // An error occurred
  console.error(err);
}

Leggi in modo asincrono dai file

Usa il modulo del filesystem per tutte le operazioni sui file:

const fs = require('fs');

Con codifica

In questo esempio, leggi hello.txt dalla directory /tmp . Questa operazione sarà completata in background e il callback si verifica al completamento o al fallimento:

fs.readFile('/tmp/hello.txt', { encoding: 'utf8' }, (err, content) => {
  // If an error occurred, output it and return
  if(err) return console.error(err);

  // No error occurred, content is a string
  console.log(content);
});

Senza codifica

Leggi il file binary.txt binario dalla directory corrente, in modo asincrono sullo sfondo. Nota che non impostiamo l'opzione 'encoding' - questo impedisce a Node.js di decodificare il contenuto in una stringa:

fs.readFile('binary', (err, binaryContent) => {
  // If an error occurred, output it and return
  if(err) return console.error(err);

  // No error occurred, content is a Buffer, output it in
  // hexadecimal representation.
  console.log(content.toString('hex'));
});

Percorsi relativi

Tieni presente che, in generale, lo script può essere eseguito con una directory di lavoro corrente arbitraria. Per indirizzare un file relativo allo script corrente, usa __dirname o __filename :

fs.readFile(path.resolve(__dirname, 'someFile'), (err, binaryContent) => {
  //Rest of Function
}

Elenco dei contenuti della directory con readdir o readdirSync

const fs = require('fs');

// Read the contents of the directory /usr/local/bin asynchronously.
// The callback will be invoked once the operation has either completed
// or failed.
fs.readdir('/usr/local/bin', (err, files) => {
  // On error, show it and return
  if(err) return console.error(err);

  // files is an array containing the names of all entries
  // in the directory, excluding '.' (the directory itself)
  // and '..' (the parent directory).

  // Display directory entries
  console.log(files.join(' '));
});

Una variante sincrona è disponibile come readdirSync che blocca il thread principale e quindi impedisce l'esecuzione di codice asincrono allo stesso tempo. La maggior parte degli sviluppatori evita le funzioni di I / O sincrone per migliorare le prestazioni.

let files;

try {
  files = fs.readdirSync('/var/tmp');
} catch(err) {
  // An error occurred
  console.error(err);
}

Utilizzando un generatore

const fs = require('fs');

// Iterate through all items obtained via
// 'yield' statements
// A callback is passed to the generator function because it is required by
// the 'readdir' method
function run(gen) {
  var iter = gen((err, data) => {
    if (err) { iter.throw(err); }

    return iter.next(data);
  });

  iter.next();
}

const dirPath = '/usr/local/bin';

// Execute the generator function
run(function* (resume) {
  // Emit the list of files in the directory from the generator
  var contents = yield fs.readdir(dirPath, resume);
  console.log(contents);
});

Lettura da un file in modo sincrono

Per qualsiasi operazione sui file, è necessario il modulo filesystem:

const fs = require('fs');

Leggere una stringa

fs.readFileSync comporta in modo simile a fs.readFile , ma non fs.readFile una richiamata poiché completa in modo sincrono e quindi blocca il thread principale. La maggior parte degli sviluppatori di node.js preferiscono le varianti asincrone che non causeranno praticamente alcun ritardo nell'esecuzione del programma.

Se viene specificata un'opzione di encoding , verrà restituita una stringa, altrimenti verrà restituito un Buffer .

// Read a string from another file synchronously
let content;
try {
  content = fs.readFileSync('sync.txt', { encoding: 'utf8' });
} catch(err) {
  // An error occurred
  console.error(err);
}

Eliminazione di un file utilizzando lo scollegamento o lo scollegamento sincronizzato

Elimina un file in modo asincrono:

var fs = require('fs');

fs.unlink('/path/to/file.txt', function(err) {
  if (err) throw err;

  console.log('file deleted');
});

Puoi anche eliminarlo in modo sincrono *:

var fs = require('fs');

fs.unlinkSync('/path/to/file.txt');
console.log('file deleted');

* evitare i metodi sincroni perché bloccano l'intero processo fino al termine dell'esecuzione.

Lettura di un file in un buffer utilizzando i flussi

Mentre leggendo il contenuto da un file è già asincrono usando il metodo fs.readFile() , a volte vogliamo ottenere i dati in un flusso rispetto a un semplice callback. Questo ci consente di convogliare questi dati in altre posizioni o di elaborarli al loro interno rispetto a tutti in una volta alla fine.

const fs = require('fs');

// Store file data chunks in this array
let chunks = [];
// We can use this variable to store the final data
let fileBuffer;

// Read file into stream.Readable
let fileStream = fs.createReadStream('text.txt');

// An error occurred with the stream
fileStream.once('error', (err) => {
    // Be sure to handle this properly!
    console.error(err); 
});

// File is done being read
fileStream.once('end', () => {
    // create the final data Buffer from data chunks;
    fileBuffer = Buffer.concat(chunks);
    
    // Of course, you can do anything else you need to here, like emit an event!
});

// Data is flushed from fileStream in chunks,
// this callback will be executed for each chunk
fileStream.on('data', (chunk) => {
    chunks.push(chunk); // push data chunk to array

    // We can perform actions on the partial data we have so far!
});

Verifica le autorizzazioni di un file o di una directory

fs.access() determina se esiste un percorso e quali autorizzazioni ha un utente per il file o la directory in quel percorso. fs.access non restituisce un risultato piuttosto, se non restituisce un errore, il percorso esiste e l'utente ha le autorizzazioni desiderate.

Le modalità di autorizzazione sono disponibili come proprietà sull'oggetto fs , fs.constants

  • fs.constants.F_OK - Ha fs.constants.F_OK lettura / scrittura / esecuzione (se non viene fornita alcuna modalità, questa è l'impostazione predefinita)
  • fs.constants.R_OK - Ha permessi di lettura
  • fs.constants.W_OK - Ha permessi di scrittura
  • fs.constants.X_OK - Ha permessi di esecuzione (Funziona come fs.constants.F_OK su Windows)

in modo asincrono

var fs = require('fs');
var path = '/path/to/check';

// checks execute permission
fs.access(path, fs.constants.X_OK, (err) => {
    if (err) {
        console.log("%s doesn't exist", path);
    } else {
        console.log('can execute %s', path);
    }
});
// Check if we have read/write permissions
// When specifying multiple permission modes
// each mode is separated by a pipe : `|`
fs.access(path, fs.constants.R_OK | fs.constants.W_OK, (err) => {
    if (err) {
        console.log("%s doesn't exist", path);
    } else {
        console.log('can read/write %s', path);
    }
});

sincrono

fs.access ha anche una versione sincrona fs.accessSync . Quando si utilizza fs.accessSync è necessario racchiuderlo all'interno di un blocco try / catch.

// Check write permission
try {
    fs.accessSync(path, fs.constants.W_OK);
    console.log('can write %s', path);
}
catch (err) {
    console.log("%s doesn't exist", path);
}

Evitare le condizioni di gara durante la creazione o l'utilizzo di una directory esistente

A causa della natura asincrona del nodo, creando o utilizzando una directory prima:

  1. controllando la sua esistenza con fs.stat() , quindi
  2. creandolo o usandolo in base ai risultati del controllo di esistenza,

può portare a una condizione di competizione se la cartella viene creata tra il momento del controllo e l'ora della creazione. Il metodo riportato di seguito fs.mkdir() e fs.mkdirSync() in wrapper che catturano gli errori che consentono il passaggio dell'eccezione se il codice è EEXIST (già esistente). Se l'errore è qualcos'altro, come EPERM (pemission negato), lancia o passa un errore come fanno le funzioni native.

Versione asincrona con fs.mkdir()

var fs = require('fs');

function mkdir (dirPath, callback) {
  fs.mkdir(dirPath, (err) => {
    callback(err && err.code !== 'EEXIST' ? err : null);
  });
}

mkdir('./existingDir', (err) => {

  if (err)
    return console.error(err.code);

  // Do something with `./existingDir` here

});

Versione sincrona con fs.mkdirSync()

function mkdirSync (dirPath) {
  try {
    fs.mkdirSync(dirPath);
  } catch(e) {
    if ( e.code !== 'EEXIST' ) throw e;
  }
}

mkdirSync('./existing-dir');
// Do something with `./existing-dir` now

Verifica se esiste un file o una directory

in modo asincrono

var fs = require('fs');

fs.stat('path/to/file', function(err) {
    if (!err) {
        console.log('file or directory exists');
    }
    else if (err.code === 'ENOENT') {
        console.log('file or directory does not exist');
    }
});

sincrono

qui, dobbiamo racchiudere la chiamata di funzione in un blocco try/catch per gestire l'errore.

var fs = require('fs');

try {
    fs.statSync('path/to/file');
    console.log('file or directory exists');
}
catch (err) {
  if (err.code === 'ENOENT') {
    console.log('file or directory does not exist');
  }
}

Clonazione di un file utilizzando i flussi

Questo programma illustra come è possibile copiare un file utilizzando flussi leggibili e scrivibili utilizzando le createReadStream() e createWriteStream() fornite dal modulo del file system.

//Require the file System module
var fs = require('fs');

/*
  Create readable stream to file in current directory (__dirname) named 'node.txt'
  Use utf8 encoding 
  Read the data in 16-kilobyte chunks
*/
var readable = fs.createReadStream(__dirname + '/node.txt', { encoding: 'utf8', highWaterMark: 16 * 1024 });

// create writable stream
var writable = fs.createWriteStream(__dirname + '/nodeCopy.txt');

// Write each chunk of data to the writable stream
readable.on('data', function(chunk) {
    writable.write(chunk);
});

Copia di file tramite streaming di piping

Questo programma copia un file utilizzando un flusso leggibile e scrivibile con la funzione pipe() fornita dalla classe stream

// require the file system module
var fs = require('fs');

/*
    Create readable stream to file in current directory named 'node.txt'
    Use utf8 encoding 
    Read the data in 16-kilobyte chunks
*/
var readable = fs.createReadStream(__dirname + '/node.txt', { encoding: 'utf8', highWaterMark: 16 * 1024 });

// create writable stream
var writable = fs.createWriteStream(__dirname + '/nodePipe.txt');

// use pipe to copy readable to writable
readable.pipe(writable);

Modifica del contenuto di un file di testo

Esempio. Sostituirà la parola email con un name in un file di testo index.txt con la semplice replace(/email/gim, 'name') RegExp replace(/email/gim, 'name')

var fs = require('fs');
 
fs.readFile('index.txt', 'utf-8', function(err, data) {
    if (err) throw err;
 
    var newValue = data.replace(/email/gim, 'name');
 
    fs.writeFile('index.txt', newValue, 'utf-8', function(err, data) {
        if (err) throw err;
        console.log('Done!');
    })
})

Determinazione del numero di righe di un file di testo

app.js

const readline = require('readline');
const fs = require('fs');

var file = 'path.to.file';
var linesCount = 0;
var rl = readline.createInterface({
    input: fs.createReadStream(file),
    output: process.stdout,
    terminal: false
});
rl.on('line', function (line) {
    linesCount++; // on each linebreak, add +1 to 'linesCount'
});
rl.on('close', function () {
    console.log(linesCount); // print the result when the 'close' event is called
});

Uso:

nodo app

Leggere un file riga per riga

app.js

const readline = require('readline');
const fs = require('fs');

var file = 'path.to.file';
var rl = readline.createInterface({
    input: fs.createReadStream(file),
    output: process.stdout,
    terminal: false
});

rl.on('line', function (line) {
    console.log(line) // print the content of the line on each linebreak
});

Uso:

nodo app



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow