var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Registri undefined, perché?
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Registri undefined, perché?
Risposte:
Per elaborare ciò che ha detto @Raynos, la funzione che hai definito è un callback asincrono. Non viene eseguito immediatamente, ma viene eseguito al termine del caricamento del file. Quando si chiama readFile, il controllo viene restituito immediatamente e viene eseguita la riga di codice successiva. Pertanto, quando si chiama console.log, il callback non è stato ancora richiamato e questo contenuto non è stato ancora impostato. Benvenuti nella programmazione asincrona.
Approcci di esempio
const fs = require('fs');
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
const content = data;
// Invoke the next step here however you like
console.log(content); // Put all of the code here (not the best solution)
processFile(content); // Or put the next step in a function and invoke it
});
function processFile(content) {
console.log(content);
}
O meglio ancora, come mostra l'esempio di Raynos, avvolgi la tua chiamata in una funzione e passa i tuoi callback. (Apparentemente questa è una pratica migliore) Penso che prendere l'abitudine di avvolgere le chiamate asincrone in una funzione che richiede una richiamata ti farà risparmiare un sacco di problemi e codice disordinato.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
'utf8'dopo il nome file come parametro aggiuntivo, altrimenti restituirà solo un buffer. Vedi: stackoverflow.com/questions/9168737/...
In realtà esiste una funzione sincrona per questo:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Legge in modo asincrono l'intero contenuto di un file. Esempio:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
Al callback vengono passati due argomenti (err, data), dove data è il contenuto del file.
Se non viene specificata alcuna codifica, viene restituito il buffer non elaborato.
fs.readFileSync(filename, [encoding])
Versione sincrona di fs.readFile. Restituisce il contenuto del file denominato nomefile.
Se viene specificata la codifica, questa funzione restituisce una stringa. Altrimenti restituisce un buffer.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }Ora abbiamo convertito il buffer in testo leggibile. Questo è utile per leggere un file in chiaro o testare il file con tipi di formato. Potrei fare un tentativo / catch per vedere se è un file JSON per esempio; ma solo dopo che il buffer è stato convertito in testo. Guarda qui per maggiori informazioni: nodejs.org/api/buffer.html
AF 42 F1. Molto pratico per la comunicazione client-server-client.
function readContent(callback) {
fs.readFile("./Index.html", function (err, content) {
if (err) return callback(err)
callback(null, content)
})
}
readContent(function (err, content) {
console.log(content)
})
function readContent(callback), è callbackuna parola riservata? Voglio dire, è questo il modo standard di implementare i callback per le tue funzioni personalizzate? Ho appena iniziato a studiare il nodo.
evento cqualsiasi nome ti piaccia - non è una parola riservata in Javascript, e presumo che lo stesso si estenda a Node.js.
readContent(function (err, content)mi dà un errore di sintassi quando si utilizza la funzione come parametro.
Il mzmodulo fornisce versioni promesse della libreria del nodo principale. Usarli è semplice. Prima installa la libreria ...
npm install mz
Poi...
const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
.catch(err => console.error(err));
In alternativa puoi scriverli in funzioni asincrone:
async function myReadfile () {
try {
const file = await fs.readFile('./Index.html');
}
catch (err) { console.error( err ) }
};
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');
usalo per chiamare un file in modo sincrono, senza codificare il suo output di visualizzazione come buffer.
Questa linea funzionerà,
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
fs.readFileSyncè il metodo di sincronizzazione, quindi non è necessario await. Attendere è utile con le promesse ( nodejs.org/api/fs.html#fs_fs_promises_api ), quando si desidera scrivere un codice asincrono con una sintassi simile al codice di sincronizzazione.
const fs = require('fs')
function readDemo1(file1) {
return new Promise(function (resolve, reject) {
fs.readFile(file1, 'utf8', function (err, dataDemo1) {
if (err)
reject(err);
else
resolve(dataDemo1);
});
});
}
async function copyFile() {
try {
let dataDemo1 = await readDemo1('url')
dataDemo1 += '\n' + await readDemo1('url')
await writeDemo2(dataDemo1)
console.log(dataDemo1)
} catch (error) {
console.error(error);
}
}
copyFile();
function writeDemo2(dataDemo1) {
return new Promise(function(resolve, reject) {
fs.writeFile('text.txt', dataDemo1, 'utf8', function(err) {
if (err)
reject(err);
else
resolve("Promise Success!");
});
});
}
modo di lettura file di sincronizzazione e asincrono:
//fs module to read file in sync and async way
var fs = require('fs'),
filePath = './sample_files/sample_css.css';
// this for async way
/*fs.readFile(filePath, 'utf8', function (err, data) {
if (err) throw err;
console.log(data);
});*/
//this is sync way
var css = fs.readFileSync(filePath, 'utf8');
console.log(css);
Node Cheat Disponibile su read_file .
Come detto, fs.readFileè un'azione asincrona. Ciò significa che quando si dice al nodo di leggere un file, è necessario considerare che ci vorrà del tempo e, nel frattempo, il nodo continua a eseguire il codice seguente. Nel tuo caso è:console.log(content); .
È come inviare una parte del codice per un lungo viaggio (come leggere un file di grandi dimensioni).
Dai un'occhiata ai commenti che ho scritto:
var content;
// node, go fetch this file. when you come back, please run this "read" callback function
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
// in the meantime, please continue and run this console.log
console.log(content);
Ecco perchè content è ancora vuoto quando lo accedi. nodo non ha ancora recuperato il contenuto del file.
Ciò potrebbe essere risolto spostandosi console.log(content)all'interno della funzione di richiamata, subito dopo content = data;. In questo modo vedrai il registro quando il nodo ha finito di leggere il file e dopo contentottiene un valore.
Utilizzare la libreria promisify integrata (Nodo 8+) per rendere più eleganti queste vecchie funzioni di callback.
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
async function doStuff() {
try {
const content = await readFile(filePath, 'utf8');
console.log(content);
} catch (e) {
console.error(e);
}
}
const doStuff = async (filePath) => fs.readFileSync(filePath, 'utf8');, non è necessario il wrapping util.promisify.
var fs = require('fs');
var path = (process.cwd()+"\\text.txt");
fs.readFile(path , function(err,data)
{
if(err)
console.log(err)
else
console.log(data.toString());
});
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Questo solo perché il nodo è asincrono e non attenderà la funzione di lettura e non appena il programma si avvia consoliderà il valore come indefinito, il che è vero perché non c'è alcun valore assegnato alla variabile di contenuto. Per gestire possiamo usare promesse, generatori ecc. Possiamo usare le promesse in questo modo.
new Promise((resolve,reject)=>{
fs.readFile('./index.html','utf-8',(err, data)=>{
if (err) {
reject(err); // in the case of error, control flow goes to the catch block with the error occured.
}
else{
resolve(data); // in the case of success, control flow goes to the then block with the content of the file.
}
});
})
.then((data)=>{
console.log(data); // use your content of the file here (in this then).
})
.catch((err)=>{
throw err; // handle error here.
})
puoi leggere il file di
var readMyFile = function(path, cb) {
fs.readFile(path, 'utf8', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Aggiungendo puoi scrivere su file,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
e persino incatenarlo insieme
var readFileAndConvertToSentence = function(path, callback) {
readMyFile(path, function(err, content) {
if (err) {
callback(err, null);
} else {
var sentence = content.split('\n').join(' ');
callback(null, sentence);
}
});
};
Per dirla in parole povere, hai a che fare con node.js che è di natura asincrona.
Quando parliamo di asincrono, stiamo parlando di fare o elaborare informazioni o dati mentre trattiamo qualcos'altro. Non è sinonimo di parallelo, si ricorda che.
Il tuo codice:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Con l'esempio, fondamentalmente esegue prima la parte console.log, quindi la variabile "contenuto" non è definita.
Se vuoi davvero l'output, fai qualcosa del genere invece:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
Questo è asincrono. Sarà difficile abituarsi ma, è quello che è. Ancora una volta, questa è una spiegazione approssimativa ma veloce di ciò che è asincrono.