var content;
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Logs undefined
, why?
var content;
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Logs undefined
, why?
To elaborate on what @Raynos said, the function you have defined is an asynchronous callback. It doesn\'t execute right away, rather it executes when the file loading has completed. When you call readFile, control is returned immediately and the next line of code is executed. So when you call console.log, your callback has not yet been invoked, and this content has not yet been set. Welcome to asynchronous programming.
Example approaches
const fs = require(\'fs\');
var content;
// First I want to read the file
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
// Invoke the next step here however you like
console.log(content); // Put all of the code here (not the best solution)
processFile(); // Or put the next step in a function and invoke it
});
function processFile() {
console.log(content);
}
Or better yet, as Raynos example shows, wrap your call in a function and pass in your own callbacks. (Apparently this is better practice) I think getting into the habit of wrapping your async calls in function that takes a callback will save you a lot of trouble and messy code.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
There is actually a Synchronous function for this:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Asynchronously reads the entire contents of a file. Example:
fs.readFile(\'/etc/passwd\', function (err, data) {
if (err) throw err;
console.log(data);
});
The callback is passed two arguments (err, data), where data is the contents of the file.
If no encoding is specified, then the raw buffer is returned.
fs.readFileSync(filename, [encoding])
Synchronous version of fs.readFile. Returns the contents of the file named filename.
If encoding is specified then this function returns a string. Otherwise it returns a buffer.
var text = fs.readFileSync(\'test.md\',\'utf8\')
console.log (text)
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)
})
The mz
module provides promisified versions of the core node library. Using them is simple. First install the library...
npm install mz
Then...
const fs = require(\'mz/fs\');
fs.readFile(\'./Index.html\').then(contents => console.log(contents))
.catch(err => console.error(err));
Alternatively you can write them in asynchronous functions:
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 this for calling a file synchronously, without encoding its showing output as a buffer.
sync and async file reading way:
//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 Available at read_file.
As said, fs.readFile
is an asynchronous action. It means that when you tell node to read a file, you need to consider that it will take some time, and in the meantime, node continued to run the following code. In your case it\'s: console.log(content);
.
It\'s like sending some part of your code for a long trip (like reading a big file).
Take a look at the comments that I\'ve written:
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);
That\'s why content
is still empty when you log it. node has not yet retrieved the file\'s content.
This could be resolved by moving console.log(content)
inside the callback function, right after content = data;
. This way you will see the log when node is done reading the file and after content
gets a value.
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!\");
});
});
}
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());
});
Use the built in promisify library (Node 8+) to make these old callback functions more elegant.
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);
}
}
you can read file by
var readMyFile = function(path, cb) {
fs.readFile(path, \'utf8\', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Adding on you can write to file,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
and even chain it together
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);
}
});
};
To put it roughly, you\'re dealing with node.js which is asynchronous in nature.
When we talk about async, we\'re talking about doing or processing info or data while dealing with something else. It is not synonymous to parallel, please be reminded.
Your code:
var content;
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
With your sample, it basically does the console.log part first, thus the variable \'content\' being undefined.
If you really want the output, do something like this instead:
var content;
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
This is asynchronous. It will be hard to get used to but, it is what it is. Again, this is a rough but fast explanation of what async is.
var content;
fs.readFile(\'./Index.html\', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
This is just because node is asynchronous and it will not wait for the read function and as soon as the program starts it will console the value as undefined, Which is actually true because there is no value assigned to content variable. To handle we can use promises, generators etc. We can use promise in this way.
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.
})