【NodeJs-5天学习】第二天篇① ——fs文件系统
面向读者群体
- ❤️ 电子物联网专业同学,想针对硬件功能构造简单的服务器,不需要学习专业的服务器开发知识 ❤️
- ❤️ 业余爱好物联网开发者,有简单技术基础,想针对硬件功能构造简单的服务器❤️
- ❤️ 本篇创建记录 2023-03-12 ❤️
- ❤️ 本篇更新记录 2023-03-12 ❤️
技术要求
- 有HTML、CSS、JavaScript基础更好,当然也没事,就直接运行实例代码学习
专栏介绍
- 通过简短5天时间的渐进式学习NodeJs,可以了解到基本的服务开发概念,同时可以学习到npm、内置核心API(FS文件系统操作、HTTP服务器、Express框架等等),最终能够完成基本的物联网web开发,而且能够部署到公网访问。
🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
1、文件系统
说到存储空间
,我们可能会很容易联想到计算机硬盘
。
而我们在硬盘上所看到的各式各样的文件或者文件目录,最终都会交给文件系统(File System)管理。
文件的概念是一个广义,一方面包括
普通大众
所认知的文件(图片、txt文件、pdf文件),另一方面主要是开发者
所熟知的文件(html、js、css、数据库db文件等等技术文件)
不管是哪种文件,我们都叫做 File
,而针对File的一系列操作:
- 创建文件
- 删除文件
- 读写文件
- 管理文件目录
- …
我们统称为文件系统的功能。而我们学习文件系统无非就是学习这些具体操作。
1.1 应用场景
- 数据信息可以存储在文件中,比如温湿度数据可以一行一个记录
- 配置信息,包括用json文件配置一些固定信息,比如可以配置一些用户信息
- web页面,包括html、css、js等文件,用途广泛
2、NodeJs fs文件模块
fs模块是nodejs官方提供的、用来本地文件系统的功能模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求。
fs模块是nodejs的核心模块之一,只要安装了nodejs,就可以直接使用,不需要单独安装。Node 导入fs模块语法如下所示:
var fs = require("fs")
fs 模块中的方法均有异步
和同步
版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
同步:一定要等到操作执行完才能执行下一步,需要阻塞
异步:不需要等到操作执行完才执行下一步,需要设置回调函数。没有特殊要求基本上只用异步方法。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。
fs模块的方法非常多,感兴趣可以查阅 Node.js中文网-fs模块 以及 Node.js 文件系统,我们大多数情况下只会用到一些常用的。
现阶段我们对于文件一般掌握几个操作即可:
- 打开、关闭文件
- 读取文件
- 写入文件
- 删除文件
- 读取文件信息
- 创建目录
- 读取目录
- 删除目录
2.1 打开文件
语法:
fs.open(path, flags[, mode], callback)
参数说明:
- path - 文件的路径。
- mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
- callback - 回调函数,带有两个参数如:callback(err, fd)。第一个为可能抛出的
异常对象
,第二个是文件系统为被打开的文件分配的数值类型的文件描述符fd
。 - flags - 文件打开的行为
举个例子:
我们在代码中创建一个 test.txt 文件,往里面写入内容“我是来自于test内容”
创建 test_fs.js文件,写入代码:
var fs = require("fs");
// 异步打开文件
console.log("准备打开文件!");
fs.open('test.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("test.txt 文件打开成功!");
});
执行代码,可以看到日志打印结果:
表示打开文件正常。
2.2 读取文件
读取文件有两种方式
- read
- readFile
2.2.1 fs.read
语法:
fs.read(fd, buffer, offset, length, position, callback)
参数说明:
- fd - 通过 fs.open() 方法返回的文件描述符。
- buffer - 数据写入的缓冲区。
- offset - 缓冲区写入的写入偏移量。
- length - 要从文件中读取的字节数。
- position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
- callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。
举个例子:
我们读取上面创建的 test.txt 文件,看看它会打印什么信息。
创建 test_fs.js文件,写入代码:
var fs = require("fs");
// 读取文件
var buf = new Buffer.alloc(1024);
console.log("准备打开已存在的文件!");
fs.open('test.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("准备读取文件:");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
console.log(bytes + " 字节被读取");
// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
});
});
执行代码,可以看到日志打印结果:
2.2.2 fs.readFile
fs.read需要我们先调用open方法,而fs.readFile则内部已经集成open,不需要人为操作。
语法:
fs.readFile(path[, options], callback)
参数说明:
- path表示文件名或文件描述符,可选参数的类型为:String、Buffer、URL、integer等类型。
- options是一个对象,包含两个属性encoding表示字符编码和flag表示文件系统标志。当没有指定字符编码时,则返回原始的 buffer,当为字符串时只能表示字符编码。
- callback表示一个回调函数,会传入两个参数 (err, data),其中 data 是文件的内容,err是错误信息,没有则为空。
举个例子:
我们读取上面创建的 test.txt 文件,看看它会打印什么信息。
创建 test_fs.js文件,写入代码(比上面代码简单):
var fs = require("fs");
// 读取文件
console.log("readFile 准备打开已存在的文件!");
fs.readFile('test.txt', 'utf8', (err, data) => {
if (err) { console.log('读取失败'); }
else {
console.log(data);
}
});
执行代码,可以看到日志打印结果:
2.3 写入文件
读取文件有两种方式
- writeFile
- appendFile
2.3.1 fs.writeFile
语法:
fs.writeFile(file, data[, options], callback)
参数说明:
- file参数为要写入的文件路径,或文件描述符。
- data为要写入的数据,支持 、 、 、等。
- options支持三个参数:encoding,默认值’utf8’;mode,权限类型,默认值0o666;flag,打开方式,默认值w。
- callback 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。
举个例子:
我们写入上面创建的 test1.txt 文件,看看它会打印什么信息。
写入代码:
var fs = require("fs");
console.log("准备写入文件");
fs.writeFile('test1.txt', '我是通 过fs.writeFile 写入文件的内容', function(err) {
if (err) {
return console.error(err);
}
console.log("数据写入成功!");
console.log("--------我是分割线-------------")
console.log("读取写入的数据!");
fs.readFile('test1.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取文件数据: " + data.toString());
});
});
执行代码,可以看到日志打印结果:
注意:
这个方法是直接覆盖掉原来的内容!!!
2.3.2 fs.appendFile
这个方法会在文件的后面追加内容
,而不是覆盖掉原来的内容。和writeFile对比一下。
语法:
fs.appendFile(path, data[, options], callback)
参数说明:
- path支持字符串、Buffer和URL类型;
- data为要追加的数据,可以是字符串或Buffer实例;
- options为配置对象,包含三个参数:
- encoding,编码方式,默认为utf8。
- mode,模式,默认为0o666。该参数为文件的权限描述,0o666表示为每个用户拥有读写权限。
- flag,文件操作方式,默认为a,即追加。
- callback为函数执行完毕的回调函数,如果追加失败,则第一个参数为错误对象,否则为undefined。
举个例子:
我们追加上面创建的 test1.txt 文件,看看它会打印什么信息。
写入代码:
var fs = require("fs");
fs.appendFile('test1.txt', '这是要添加的数据', (err) => {
if (err) {
console.log('数据追加失败');
} else {
console.log('数据追加成功');
}
});
执行代码,可以看到日志打印结果:
可以看到,新增内容的确是追加到文件末尾。
2.4 删除文件
语法:
fs.unlink(path, callback)
参数说明:
- path - 文件的路径。
- callback - 回调函数,没有参数。
举个例子:
我们删除上面创建的 test.txt 文件,看看它会打印什么信息。
写入代码:
var fs = require("fs");
console.log("test.txt 准备删除文件!");
fs.unlink('test.txt', function(err) {
if (err) {
return console.error(err);
}
console.log("文件删除成功!");
});
执行代码,可以看到日志打印结果:
2.5 读取文件信息
语法:
fs.stat(path, callback)
参数说明:
- path - 文件的路径。
- callback - 回调函数,带有两个参数如:(err, stats), stats 是
fs.Stats
对象。fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。
举个例子:
我们判断上面创建的 test.txt 文件,看看它会打印什么信息。
写入代码:
var fs = require("fs");
// 读取文件信息
console.log("准备打开文件!");
fs.stat('test.txt', function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("读取文件 test.txt 信息成功!");
// 检测文件类型
console.log("是否为文件(isFile) ? " + stats.isFile());
console.log("是否为目录(isDirectory) ? " + stats.isDirectory());
});
执行代码,可以看到日志打印结果:
fs.Stats实例属性:
Stats {
dev: 2114, // 设备的数字标识符
ino: 48064969, // 设备的索引号
mode: 33188, // 文件类型和模式
nlink: 1, // 文件的硬链接数
uid: 85, // 该文件拥有者的标识符
gid: 100, // 拥有该文件的群组的标识符
rdev: 0, // 数字型设备表标识符
size: 527, // 文件大小,单位为字节
blksize: 4096, // 文件系统块的大小
blocks: 8, // 文件系统为当前文件分配的块数
atimeMs: 1318289051000.1, // 上次被访问时间
mtimeMs: 1318289051000.1, // 上次被修改的时间
ctimeMs: 1318289051000.1, // 上次更改文件状态的时间
birthtimeMs: 1318289051000.1, // 文件的创建时间
atime: Mon, 10 Oct 2011 23:24:11 GMT, // 以上四个时间的另一种格式
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
2.6 关闭文件
语法:
fs.close(fd, callback)
参数说明:
- fd - 通过 fs.open() 方法返回的文件描述符。
- callback - 回调函数,没有参数。
举个例子:
我们关闭上面创建的 test.txt 文件,看看它会打印什么信息。
创建 test_fs.js文件,写入代码(比上面代码简单):
var fs = require("fs");
var buf = new Buffer.alloc(1024);
console.log("准备打开文件!");
fs.open('test.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("准备读取文件!");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
// 关闭文件
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("文件关闭成功");
});
});
});
执行代码,可以看到日志打印结果:
2.7 创建目录
语法:
fs.mkdir(path[, options], callback)
参数说明:
- path - 文件路径。
- options 参数可以是:
- recursive - 是否以递归的方式创建目录,默认为 false。false的话如果我们想创建目录下的目录,不存在的话会创建失败,一般设置为true。
- mode - 设置目录权限,默认为 0777。
- callback - 回调函数,没有参数。
举个例子:
我们在当前项目目录根目录创建一个/tmp/test/,看看它会打印什么信息。
创建 test_fs.js文件,写入代码(比上面代码简单):
var fs = require("fs");
// tmp 目录必须存在
console.log("创建目录 ./tmp/test/");
fs.mkdir("./tmp/test/",{ recursive: true },function(err){
if (err) {
return console.error(err);
}
console.log("目录创建成功。");
});
执行代码,可以看到日志打印结果:
2.8 读取目录
语法:
fs.readdir(path, callback)
参数说明:
- path - 文件路径。
- callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。
举个例子:
我们在上面创建一个/tmp/test/下复制多几个文件,看看它会打印什么信息。
创建 test_fs.js文件,写入代码(比上面代码简单):
var fs = require("fs");
console.log("查看 ./tmp/test/ 目录");
fs.readdir("./tmp/test/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
执行代码,可以看到日志打印结果:
2.9 删除目录
语法:
fs.rmdir(path, callback)
参数说明:
- path - 文件路径。(注意;该路径下不能存在文件,必须是
空目录
) - callback - 回调函数,没有参数。
举个例子:
我们删除上面创建的/tmp/test/目录,看看它会打印什么信息。
创建 test_fs.js文件,写入代码(比上面代码简单):
var fs = require("fs");
// 执行前创建一个空的 ./tmp/test 目录
console.log("准备删除目录 ./tmp/test");
fs.rmdir("./tmp/test",function(err){
if (err) {
return console.error(err);
}
console.log("读取 /tmp 目录");
fs.readdir("./tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
执行代码,可以看到日志打印结果:
清空一下test目录里面的所有文件,再次执行代码看看:
3、总结
篇①主要是通过简单学习fs文件模块来操作服务器存储系统,后面会在配置信息或者存储客户端信息用到。