var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Registros undefined
, ¿por qué?
fuente
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Registros undefined
, ¿por qué?
Para explicar en detalle lo que dijo @Raynos, la función que ha definido es una devolución de llamada asincrónica. No se ejecuta de inmediato, sino que se ejecuta cuando se completa la carga del archivo. Cuando llama a readFile, el control se devuelve inmediatamente y se ejecuta la siguiente línea de código. Entonces, cuando llama a console.log, su devolución de llamada aún no se ha invocado y este contenido aún no se ha configurado. Bienvenido a la programación asincrónica.
Enfoques de ejemplo
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 mejor aún, como muestra el ejemplo de Raynos, envuelva su llamada en una función y pase sus propias devoluciones de llamada. (Aparentemente, esta es una mejor práctica) Creo que adquirir el hábito de envolver sus llamadas asíncronas en una función que tome una devolución de llamada le ahorrará muchos problemas y códigos desordenados.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
'utf8'
después del nombre de archivo como parámetro adicional, de lo contrario, solo devolverá un búfer. Ver: stackoverflow.com/questions/9168737/…
En realidad, hay una función síncrona para esto:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Lee asincrónicamente todo el contenido de un archivo. Ejemplo:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
La devolución de llamada pasa dos argumentos (err, data), donde data es el contenido del archivo.
Si no se especifica codificación, se devuelve el búfer sin procesar.
fs.readFileSync(filename, [encoding])
Versión sincrónica de fs.readFile. Devuelve el contenido del archivo llamado nombre de archivo.
Si se especifica la codificación, esta función devuelve una cadena. De lo contrario, devuelve un búfer.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
data
. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }
Ahora hemos convertido el búfer en texto legible. Esto es bueno para leer un archivo de texto sin formato o probar el archivo con los tipos de formato. Podría hacer un try / catch para ver si es un archivo JSON, por ejemplo; pero solo después de que el búfer se convierta en texto. Mire aquí para obtener más información: nodejs.org/api/buffer.html
AF 42 F1
. Muy práctico para la comunicación cliente-servidor-cliente.
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)
, ¿es callback
una palabra reservada? Quiero decir, ¿es esta la forma estándar de implementar devoluciones de llamada para sus funciones personalizadas? Acabo de empezar a aprender nodo.
event
o c
cualquier nombre que desee, no es una palabra reservada en Javascript, y supongo que lo mismo se extiende a Node.js.
readContent(function (err, content)
me da un error de sintaxis al usar la función como parámetro.
El mz
módulo proporciona versiones prometidas de la biblioteca del nodo central. Usarlos es simple. Primero instale la biblioteca ...
npm install mz
Luego...
const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
.catch(err => console.error(err));
Alternativamente, puede escribirlos en funciones asincrónicas:
async function myReadfile () {
try {
const file = await fs.readFile('./Index.html');
}
catch (err) { console.error( err ) }
};
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');
use esto para llamar a un archivo sincrónicamente, sin codificar su salida de muestra como un búfer.
Esta línea funcionará
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
fs.readFileSync
es un método de sincronización, por lo que no es necesario await
. Aguardar es útil con promesas ( nodejs.org/api/fs.html#fs_fs_promises_api ), cuando desea escribir código asíncrono con una sintaxis similar al código de sincronización.
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!");
});
});
}
sincronización y lectura de archivos asíncronos:
//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 Disponible en read_file .
Como se dijo, fs.readFile
es una acción asincrónica. Significa que cuando le dice al nodo que lea un archivo, debe tener en cuenta que tomará algún tiempo y, mientras tanto, el nodo continuó ejecutando el siguiente código. En tu caso es:console.log(content);
.
Es como enviar una parte de su código para un viaje largo (como leer un archivo grande).
Echa un vistazo a los comentarios que he escrito:
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);
Es por eso content
que todavía está vacío cuando lo registras. El nodo aún no ha recuperado el contenido del archivo.
Esto podría resolverse moviéndose console.log(content)
dentro de la función de devolución de llamada, justo después content = data;
. De esta manera, verá el registro cuando el nodo termine de leer el archivo y luego content
obtenga un valor.
Use la biblioteca de promisify incorporada (Nodo 8+) para hacer que estas antiguas funciones de devolución de llamada sean más elegantes.
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');
, sin necesidad de util.promisify wrap.
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);
Esto es solo porque el nodo es asíncrono y no esperará la función de lectura y tan pronto como el programa se inicie, consolará el valor como indefinido, lo cual es realmente cierto porque no hay un valor asignado a la variable de contenido. Para manejar podemos usar promesas, generadores, etc. Podemos usar promesas de esta manera.
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.
})
La siguiente función funcionaría para async
encapsular o then
cadenas de promesa
const readFileAsync = async (path) => fs.readFileSync(path, 'utf8');
puedes leer el archivo por
var readMyFile = function(path, cb) {
fs.readFile(path, 'utf8', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Agregando puede escribir en el archivo,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
e incluso encadenarlo
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);
}
});
};
Para decirlo más o menos, se trata de node.js, que es de naturaleza asíncrona.
Cuando hablamos de asíncrono, estamos hablando de hacer o procesar información o datos mientras tratamos con otra cosa. No es sinónimo de paralelo, recuerde.
Tu codigo:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Con su muestra, básicamente hace primero la parte de console.log, por lo tanto, la variable 'contenido' no está definida.
Si realmente quieres la salida, haz algo como esto en su lugar:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
Esto es asincrónico. Será difícil acostumbrarse, pero es lo que es. Nuevamente, esta es una explicación aproximada pero rápida de lo que es asíncrono.