Recherche…


Remarques

Dans Node.js, les opérations gourmandes en ressources telles que les E / S sont effectuées de manière asynchrone , mais ont un pendant synchrone (par exemple, il existe un fs.readFile et son homologue est fs.readFileSync ). Étant donné que Node est mono-thread, vous devez faire attention lorsque vous utilisez des opérations synchrones , car elles bloqueront tout le processus.

Si un processus est bloqué par une opération synchrone, tout le cycle d'exécution (y compris la boucle d'événement) est arrêté. Cela signifie qu'aucun autre code asynchrone, y compris les événements et les gestionnaires d'événements, ne s'exécutera pas et que votre programme continuera d'attendre la fin de l'opération de blocage unique.

Il existe des utilisations appropriées pour les opérations synchrones et asynchrones, mais il faut veiller à les utiliser correctement.

Écrire dans un fichier en utilisant writeFile ou 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 se comporte de la même manière que fs.writeFile , mais ne prend pas de rappel car il se termine de manière synchrone et bloque donc le thread principal. La plupart des développeurs node.js préfèrent les variantes asynchrones qui ne causent pratiquement aucun retard dans l'exécution du programme.

Remarque: le blocage du thread principal est une mauvaise pratique dans node.js. La fonction synchrone ne doit être utilisée que lors du débogage ou lorsque aucune autre option n'est disponible.

// 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);
}

Lecture asynchrone à partir de fichiers

Utilisez le module de système de fichiers pour toutes les opérations sur les fichiers:

const fs = require('fs');

Avec encodage

Dans cet exemple, lisez hello.txt partir du répertoire /tmp . Cette opération sera terminée en arrière-plan et le rappel se produit à la fin ou en cas d'échec:

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);
});

Sans codage

Lisez le fichier binaire binary.txt du répertoire en cours, de manière asynchrone en arrière-plan. Notez que nous ne définissons pas l'option "encoding" - cela empêche Node.js de décoder le contenu en une chaîne:

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'));
});

Chemins relatifs

Gardez à l'esprit que, dans le cas général, votre script peut être exécuté avec un répertoire de travail courant arbitraire. Pour adresser un fichier par rapport au script en cours, utilisez __dirname ou __filename :

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

Liste du contenu du répertoire avec readdir ou 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(' '));
});

Une variante synchrone est disponible sous la forme readdirSync qui bloque le thread principal et empêche donc l'exécution du code asynchrone en même temps. La plupart des développeurs évitent les fonctions d'E / S synchrones pour améliorer les performances.

let files;

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

En utilisant un générateur

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);
});

Lecture d'un fichier de manière synchrone

Pour toute opération de fichier, vous aurez besoin du module de système de fichiers:

const fs = require('fs');

Lire une chaîne

fs.readFileSync se comporte de la même manière que fs.readFile , mais ne prend pas de rappel car il se termine de manière synchrone et bloque donc le thread principal. La plupart des développeurs node.js préfèrent les variantes asynchrones qui ne causent pratiquement aucun retard dans l'exécution du programme.

Si une option de encoding est spécifiée, une chaîne sera renvoyée, sinon un Buffer sera renvoyé.

// 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);
}

Supprimer un fichier de manière asynchrone:

var fs = require('fs');

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

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

Vous pouvez également le supprimer de manière synchrone *:

var fs = require('fs');

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

* éviter les méthodes synchrones car elles bloquent tout le processus jusqu'à la fin de l'exécution.

Lecture d'un fichier dans un tampon à l'aide de flux

Bien que la lecture du contenu d'un fichier soit déjà asynchrone à l'aide de la méthode fs.readFile() , nous souhaitons parfois obtenir les données dans un flux plutôt que dans un simple rappel. Cela nous permet de canaliser ces données vers d’autres emplacements ou de les traiter en même temps qu’à la fin.

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!
});

Vérifier les autorisations d'un fichier ou d'un répertoire

fs.access() détermine si un chemin existe et quelles autorisations un utilisateur a au fichier ou au répertoire sur ce chemin. fs.access ne fs.access pas un résultat, mais s'il ne renvoie pas d'erreur, le chemin existe et l'utilisateur dispose des autorisations souhaitées.

Les modes d'autorisation sont disponibles en tant que propriété sur l'objet fs , fs.constants

  • fs.constants.F_OK - A des autorisations de lecture / écriture / exécution (si aucun mode n'est fourni, c'est le mode par défaut)
  • fs.constants.R_OK - A des autorisations de lecture
  • fs.constants.W_OK - A des autorisations d'écriture
  • fs.constants.X_OK - Possède des autorisations d'exécution (Fonctionne comme fs.constants.F_OK sous Windows)

Asynchrone

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);
    }
});

De manière synchrone

fs.access également une version synchrone fs.accessSync . Lorsque vous utilisez fs.accessSync vous devez le fs.accessSync dans un bloc 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);
}

Éviter les conditions de course lors de la création ou de l'utilisation d'un répertoire existant

En raison de la nature asynchrone de Node, créer ou utiliser un répertoire en premier:

  1. vérifier son existence avec fs.stat() , puis
  2. en créant ou en l'utilisant en fonction des résultats du contrôle d'existence,

peut conduire à une condition de concurrence si le dossier est créé entre l'heure de la vérification et l'heure de la création. La méthode ci-dessous fs.mkdir() et fs.mkdirSync() dans des wrappers de capture d'erreur qui laissent passer l'exception si son code est EEXIST (existe déjà). Si l'erreur est autre chose, comme EPERM (pemission denied), lancez ou passez une erreur comme le font les fonctions natives.

Version asynchrone avec 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

});

Version synchrone avec 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

Vérifier si un fichier ou un répertoire existe

Asynchrone

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');
    }
});

De manière synchrone

ici, nous devons envelopper l'appel de fonction dans un bloc try/catch pour gérer l'erreur.

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');
  }
}

Cloner un fichier en utilisant des flux

Ce programme illustre comment on peut copier un fichier en utilisant des flux lisibles et inscriptibles en utilisant les fonctions createReadStream() et createWriteStream() fournies par le module de système de fichiers.

//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);
});

Copie de fichiers par flux de tuyauterie

Ce programme copie un fichier en utilisant un flux lisible et un flux accessible en écriture avec la fonction pipe() fournie par la classe de flux

// 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);

Changer le contenu d'un fichier texte

Exemple. Il remplacera le mot email par un name dans un fichier texte index.txt avec un simple 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!');
    })
})

Détermination du nombre de lignes d'un fichier texte

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
});

Usage:

application de noeud

Lecture d'un fichier ligne par ligne

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
});

Usage:

application de noeud



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow