stdin, stdout, stderr
Below code shows how to use stdin, stdout and stderr in nodejs.
process.stdin.on("data", (data) => {
const name = data.toString().trim();
if (name !== "") {
process.stdout.write("name: " + name + "\n");
} else {
process.stderr.write("invalid name");
process.exit();
}
});
Let's see the process.
$ node index.js
Tom
name: Tom
Jack
name: Jack
File Read/Write Sync
The most simple way to read/write file is to use the readFileSync
and writeFileSync
api.
const fs = require("fs");
let contents1 = fs.readFileSync("hello.txt", { encoding: "utf-8" });
console.log(contents1.toString());
fs.writeFileSync("hello.txt", "write to hello file", { encoding: "utf8" });
let contents2 = fs.readFileSync("hello.txt", { encoding: "utf-8" });
console.log(contents2.toString());
File Read/Write Callback Async
Callback is the traditional way for nodejs to handle async operations.
const fs = require("fs");
fs.readFile("hello.txt", { encoding: "utf-8" }, (err, contents) => {
if (err) {
console.error(err);
} else {
console.log(contents.toString());
fs.writeFile( "hello.txt", "write to hello file", { encoding: "utf-8" }, (err) => {
if (err) {
console.error(err);
} else {
fs.readFile( "hello.txt", { encoding: "utf-8" }, (err, contents) => {
if (err) {
console.error(err);
} else {
console.log(contents.toString());
}
}
);
}
}
);
}
});
As you can see, it is pretty long for integrate several callbacks together.
File Read/Write Promise Async
Promise is the most recommended way to handle async operations.
const fs = require("fs").promises;
Promise.resolve()
.then(() => {
return fs.readFile("hello.txt", { encoding: "utf8" });
})
.then((contents) => {
console.log(contents.toString());
})
.then(() => {
fs.writeFile("hello.txt", "write to hello file", { encoding: "utf-8" });
})
.then(() => {
return fs.readFile("hello.txt", { encoding: "utf-8" });
})
.then((contents) => {
console.log(contents.toString());
})
.catch((err) => {
console.error(err);
});
As you can see, we have 3 type api for handling file IO in nodejs: the sync api, the callback-based async api and the promised-based async api. In nodejs, a lot of apis have these 3 types. For async operations, it is always recommended to use promise-based api.
Access File Metadata
const fs = require("fs").promises;
fs.stat("hello.txt")
.then((stats) => {
console.log(stats);
})
.catch((err) => {
console.error(err);
});
Stats {
dev: 16777221,
mode: 33188,
nlink: 1,
uid: 502,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 8637948036,
size: 19,
blocks: 8,
atimeMs: 1658405488047.815,
mtimeMs: 1658405486844.7258,
ctimeMs: 1658405486844.7258,
birthtimeMs: 1658404778790.4702,
atime: 2022-07-21T12:11:28.048Z,
mtime: 2022-07-21T12:11:26.845Z,
ctime: 2022-07-21T12:11:26.845Z,
birthtime: 2022-07-21T11:59:38.790Z
}
File Permissions And Access
In below code, we use fs.chmod
to change file permissions and fs.access
to test it.
const fs = require("fs").promises;
const { constants } = require("fs");
Promise.resolve()
.then(() => {
return fs.chmod("hello.txt", 0o000);
})
.then(() => {
console.log("chmod success");
})
.catch(() => {
console.error("chmod fail");
})
.then(() => {
return fs.access("./hello.txt", constants.R_OK | constants.W_OK);
})
.then(() => {
console.log("can access");
})
.catch(() => {
console.error("cannot access");
})
.then(() => {
return fs.chmod("hello.txt", 0o777);
})
.then(() => {
console.log("chmod success");
})
.catch(() => {
console.error("chmod fail");
})
.then(() => {
return fs.access("./hello.txt", constants.R_OK | constants.W_OK);
})
.then(() => {
console.log("can access");
})
.catch(() => {
console.error("cannot access");
});
$ node index.js
chmod success
cannot access
chmod success
can access
Watch File
In nodejs, we can use fs.watch
to watch file changes.
const fs = require("fs").promises;
(async () => {
try {
const watcher = fs.watch("hello.txt");
for await (const event of watcher) console.log(event);
} catch (err) {
console.error(err);
}
})();
$ node index.js
{ eventType: 'change', filename: 'hello.txt' }
{ eventType: 'change', filename: 'hello.txt' }
{ eventType: 'change', filename: 'hello.txt' }
{ eventType: 'change', filename: 'hello.txt' }
{ eventType: 'rename', filename: 'hello.txt' }