Sök…


Anmärkningar

I Node.js utförs resursintensiva operationer som I / O asynkront men har en synkron motsvarighet (t.ex. finns det en fs.readFile och dess motsvarighet är fs.readFileSync ). Eftersom Node är enkeltrådad, bör du vara försiktig när du använder synkrona operationer, eftersom de blockerar hela processen.

Om en process blockeras av en synkron operation stoppas hela exekveringscykeln (inklusive händelsslingan). Det betyder att annan asynkron kod, inklusive händelser och händelseshanterare, inte kommer att köras och ditt program kommer att fortsätta att vänta tills den enda blockeringsoperationen har slutförts.

Det finns lämpliga användningar för både synkrona och asynkrona operationer, men man måste se till att de används korrekt.

Skriva till en fil med writeFile eller 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 fungerar på samma sätt som fs.writeFile , men tar inte ett återuppringning eftersom det slutförs synkront och därför blockerar huvudtråden. De flesta utvecklare av node.js föredrar de asynkrona varianterna som nästan inte kommer att försena programutförandet.

Obs! Att blockera huvudtråden är dålig praxis i node.js. Synkronfunktion ska endast användas vid felsökning eller när inga andra alternativ är tillgängliga.

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

Asynkront läs från filer

Använd filsystemmodulen för alla filåtgärder:

const fs = require('fs');

Med kodning

I det här exemplet, läs hello.txt från katalogen /tmp . Denna åtgärd kommer att slutföras i bakgrunden och återuppringningen sker vid slutförande eller misslyckande:

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

Utan kodning

Läs den binära filen binary.txt från den aktuella katalogen, asynkront i bakgrunden. Observera att vi inte ställer in alternativet 'kodning' - detta förhindrar Node.js från att avkoda innehållet till en sträng:

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

Relativa vägar

Kom ihåg att ditt skript i allmänhet kan köras med en godtycklig aktuell arbetskatalog. För att adressera en fil i förhållande till det aktuella skriptet använder du __dirname eller __filename :

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

Lista kataloginnehåll med readdir eller 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(' '));
});

En synkron variant finns som readdirSync som blockerar readdirSync och därför förhindrar körning av asynkron kod samtidigt. De flesta utvecklare undviker synkrona IO-funktioner för att förbättra prestandan.

let files;

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

Med hjälp av en generator

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

Läser från en fil synkront

För alla filoperationer behöver du filsystemmodulen:

const fs = require('fs');

Läsa en sträng

fs.readFileSync beter sig på samma sätt som fs.readFile , men tar inte ett återuppringning eftersom det slutförs synkront och därför blockerar huvudtråden. De flesta utvecklare av node.js föredrar de asynkrona varianterna som nästan inte kommer att försena programutförandet.

Om ett encoding anges returneras en sträng, annars returneras en 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);
}

Radera en fil asynkront:

var fs = require('fs');

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

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

Du kan också ta bort det synkront *:

var fs = require('fs');

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

* Undvik synkrona metoder eftersom de blockerar hela processen tills körningen är klar.

Läsa en fil i en buffert med strömmar

Medan läsning av innehåll från en fil redan är asynkron med fs.readFile() -metoden, vill vi ibland få fs.readFile() i en Stream kontra i en enkel återuppringning. Detta gör att vi kan leda denna information till andra platser eller bearbeta dem när de kommer i motsats samtidigt i slutet.

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

Kontrollera behörigheter för en fil eller katalog

fs.access() avgör om en sökväg finns och vilka behörigheter en användare har till filen eller katalogen på den sökvägen. fs.access inte ett resultat snarare, om det inte returnerar ett fel finns sökvägen och användaren har önskade behörigheter.

Tillståndslägen är tillgängliga som en egenskap på fs objektet, fs.constants

  • fs.constants.F_OK - Har läs / skriv / kör körningar (Om inget läge tillhandahålls är detta standard)
  • fs.constants.R_OK - Har fs.constants.R_OK
  • fs.constants.W_OK - Har fs.constants.W_OK
  • fs.constants.X_OK - Har körningar (fungerar på samma sätt som fs.constants.F_OK på Windows)

asynkront

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

synkront

fs.access har också en synkron version fs.accessSync . När du använder fs.accessSync måste du bifoga det i ett try / catch-block.

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

Undvika tävlingsvillkor när du skapar eller använder en befintlig katalog

På grund av Nodes asynkrona natur skapar eller använder du en katalog först:

  1. kontrollera om det finns med fs.stat() , då
  2. skapa eller använda den beroende på resultaten av existenskontrollen,

kan leda till ett tävlingsvillkor om mappen skapas mellan tidpunkten för kontrollen och skapelsestiden. Metoden nedan fs.mkdir() och fs.mkdirSync() i felupptagande omslag som låter undantaget passera om dess kod är EEXIST (finns redan). Om felet är något annat, som EPERM (pemission nekad), kasta eller skicka ett fel som de ursprungliga funktionerna gör.

Asynkron version med 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

});

Synkron version med 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

Kontrollera om en fil eller en katalog finns

asynkront

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

synkront

här måste vi pakka in funktionssamtalet i ett try/catch block för att hantera fel.

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

Kloning av en fil med strömmar

Detta program illustrerar hur man kan kopiera en fil med läsbara och skrivbara strömmar med createReadStream() och createWriteStream() tillhandahålls av filsystemmodulen.

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

Kopiera filer genom pipingströmmar

Detta program kopierar en fil med hjälp av läsbar och en skrivbar ström med funktionen pipe() tillhandahålls av strömklassen

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

Ändra innehållet i en textfil

Exempel. Det kommer att ersätta ordet email till ett name i en textfil index.txt med enkel 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!');
    })
})

Bestämning av räkneantalet för en textfil

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

Användande:

nod app

Läsa en fil rad för rad

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

Användande:

nod app



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow