Node.js
Dateisystem-E / A
Suche…
Bemerkungen
In Node.js werden ressourcenintensive Operationen wie E / A asynchron ausgeführt , haben jedoch ein synchrones Gegenstück (z. B. gibt es ein fs.readFile
und sein Gegenstück ist fs.readFileSync
). Da es sich bei Node nur um einen Thread handelt, sollten Sie bei der Verwendung synchroner Operationen vorsichtig sein, da sie den gesamten Prozess blockieren.
Wenn ein Prozess durch einen synchronen Vorgang blockiert wird, wird der gesamte Ausführungszyklus (einschließlich der Ereignisschleife) angehalten. Das bedeutet, dass anderer asynchroner Code, einschließlich Events und Event-Handler, nicht ausgeführt wird und Ihr Programm so lange wartet, bis der einzelne Blockierungsvorgang abgeschlossen ist.
Es gibt geeignete Verwendungen sowohl für synchrone als auch für asynchrone Operationen. Es muss jedoch darauf geachtet werden, dass sie ordnungsgemäß verwendet werden.
Schreiben in eine Datei mit writeFile oder 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
verhält sich ähnlich wie fs.writeFile
, nimmt jedoch keinen Rückruf an, da es synchron ausgeführt wird, und blockiert daher den Haupt-Thread. Die meisten node.js-Entwickler bevorzugen die asynchronen Varianten, die praktisch keine Verzögerung bei der Programmausführung verursachen.
Anmerkung: Das Sperren des Hauptthreads ist in node.js unangebracht. Die Synchronfunktion sollte nur beim Debuggen verwendet werden oder wenn keine anderen Optionen verfügbar sind.
// 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);
}
Asynchron aus Dateien lesen
Verwenden Sie das Dateisystemmodul für alle Dateivorgänge:
const fs = require('fs');
Mit Kodierung
Lesen hello.txt
in diesem Beispiel hello.txt
aus dem Verzeichnis /tmp
. Dieser Vorgang wird im Hintergrund abgeschlossen und der Rückruf erfolgt nach Abschluss oder Fehler:
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);
});
Ohne Kodierung
Lesen Sie die Binärdatei binary.txt
asynchron im Hintergrund aus dem aktuellen Verzeichnis. Beachten Sie, dass wir die Option 'encoding' nicht festlegen - dies verhindert, dass Node.js den Inhalt in einen String decodiert:
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'));
});
Relative Pfade
Beachten Sie, dass Ihr Skript im Allgemeinen mit einem beliebigen aktuellen Arbeitsverzeichnis ausgeführt werden kann. Um eine Datei relativ zum aktuellen Skript zu adressieren, verwenden Sie __dirname
oder __filename
:
fs.readFile(path.resolve(__dirname, 'someFile'), (err, binaryContent) => {
//Rest of Function
}
Verzeichnisinhalt mit readdir oder readdirSync auflisten
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(' '));
});
Als readdirSync
gibt es eine synchrone Variante, die den Haupt-Thread blockiert und somit die gleichzeitige Ausführung von asynchronem Code verhindert. Die meisten Entwickler vermeiden synchrone E / A-Funktionen, um die Leistung zu verbessern.
let files;
try {
files = fs.readdirSync('/var/tmp');
} catch(err) {
// An error occurred
console.error(err);
}
Verwendung eines Generators
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);
});
Synchron aus einer Datei lesen
Für alle Dateioperationen benötigen Sie das Dateisystemmodul:
const fs = require('fs');
Einen String lesen
fs.readFileSync
verhält sich ähnlich wie fs.readFile
, nimmt jedoch keinen Rückruf an, da es synchron ausgeführt wird, und blockiert daher den Haupt-Thread. Die meisten node.js-Entwickler bevorzugen die asynchronen Varianten, die praktisch keine Verzögerung bei der Programmausführung verursachen.
Wenn eine encoding
angegeben wird, wird eine Zeichenfolge zurückgegeben, andernfalls wird ein Buffer
zurückgegeben.
// 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);
}
Löschen einer Datei mit unlink oder unlinkSync
Datei asynchron löschen:
var fs = require('fs');
fs.unlink('/path/to/file.txt', function(err) {
if (err) throw err;
console.log('file deleted');
});
Sie können es auch synchron löschen *:
var fs = require('fs');
fs.unlinkSync('/path/to/file.txt');
console.log('file deleted');
* Vermeiden Sie synchrone Methoden, da sie den gesamten Prozess blockieren, bis die Ausführung abgeschlossen ist.
Eine Datei mit Streams in einen Puffer lesen
Während das Lesen von Inhalten aus einer Datei mit der Methode fs.readFile()
bereits asynchron ist, fs.readFile()
wir manchmal die Daten in einem Stream und nicht in einem einfachen Rückruf abrufen. Dies ermöglicht es uns, diese Daten an andere Standorte weiterzuleiten oder am Ende auf einmal zu verarbeiten.
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!
});
Überprüfen Sie die Berechtigungen einer Datei oder eines Verzeichnisses
fs.access()
bestimmt, ob ein Pfad vorhanden ist und welche Berechtigungen ein Benutzer für die Datei oder das Verzeichnis in diesem Pfad hat. fs.access
gibt kein Ergebnis zurück. Wenn kein Fehler zurückgegeben wird, ist der Pfad vorhanden und der Benutzer verfügt über die gewünschten Berechtigungen.
Die Berechtigungsmodi sind als Eigenschaft für das fs
Objekt fs.constants
-
fs.constants.F_OK
- Hat Lese- / Schreib- / Ausführungsberechtigungen (Wenn kein Modus angegeben ist, ist dies der Standard). -
fs.constants.R_OK
- Hat Leseberechtigungen -
fs.constants.W_OK
- Verfügt über Schreibberechtigungen -
fs.constants.X_OK
- hat Ausführungsberechtigungen (funktioniert genauso wiefs.constants.F_OK
unter Windows)
Asynchron
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);
}
});
Synchron
fs.access
hat auch eine synchrone Version fs.accessSync
. Wenn Sie fs.accessSync
, müssen Sie es in einen try / catch-Block einschließen.
// 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);
}
Vermeiden von Race-Bedingungen beim Erstellen oder Verwenden eines vorhandenen Verzeichnisses
Aufgrund der asynchronen Natur des Knotens müssen Sie zunächst ein Verzeichnis erstellen oder verwenden:
-
fs.stat()
mitfs.stat()
Existenzfs.stat()
- abhängig von den Ergebnissen der Existenzprüfung erstellen oder verwenden,
kann zu einer Race-Bedingung führen, wenn der Ordner zwischen dem Zeitpunkt der Prüfung und dem Zeitpunkt der Erstellung erstellt wird. Die unten fs.mkdir()
Methode fs.mkdir()
und fs.mkdirSync()
in Wrapper zum fs.mkdirSync()
Fehlern, die die Ausnahme passieren lassen, wenn der Code EEXIST
(bereits vorhanden). Wenn der Fehler etwas anderes ist, wie EPERM
(Pemission denied), werfen Sie einen Fehler aus, oder übergeben Sie ihn, wie es die nativen Funktionen tun.
Asynchrone Version mit 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 });
Synchronversion mit 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
Überprüfen, ob eine Datei oder ein Verzeichnis vorhanden ist
Asynchron
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');
}
});
Synchron
Hier müssen wir den Funktionsaufruf in einen try/catch
Block einschließen, um Fehler zu behandeln.
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');
}
}
Klonen einer Datei mithilfe von Streams
Dieses Programm veranschaulicht, wie Sie eine Datei mithilfe von lesbaren und beschreibbaren Streams mithilfe von createReadStream()
und den vom Dateisystemmodul bereitgestellten createWriteStream()
Funktionen createWriteStream()
.
//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);
});
Kopieren von Dateien durch Piping-Streams
Dieses Programm kopiert eine Datei mit einem lesbaren und einem beschreibbaren Stream mit der Funktion pipe()
, die von der Stream-Klasse bereitgestellt wird
// 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);
Inhalt einer Textdatei ändern
Beispiel. Es wird das Wort ersetzen email
- name
index.txt
replace(/email/gim, 'name')
email
an einen name
in einer Textdatei index.txt
mit einfachen RegExp replace(/email/gim, 'name')
- 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!');
})
})
Ermitteln der Zeilenanzahl einer Textdatei
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
});
Verwendungszweck:
Knoten App
Eine Datei Zeile für Zeile lesen
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
});
Verwendungszweck:
Knoten App