Node.Js入门(fs模块)

106 阅读5分钟

什么是Node.js

我在这里就运用官方的定义来说明,官方的定义为:Node.js is an open-source,cross-platform JavaScript runtime environment.翻译就是:Node.js是一个开源且跨平台的JavaScript运行环境。

上面可能还不理解,说白了它就是一款应用程序、一款软件,可以运行JavaScript。

Node.js的作用是什么,为什么要学它呢?

Node.js的作用主要有三种:

  • 开发服务器应用:一堆硬件组成服务器,Node.js就是里面的软件,硬件保存了页面相应的html,css,js。我们可以通过URL进行访问,而其中返回数据的操作就是Node.js返回的。
  • 开发工具类应用:webpack、Vite、Bable等。
  • 开发桌面端应用:例如vscod,postman,figma等等,这些都是基于electron框架开发的,而它又是基于Node.js开发的。

命令行工具

我们都是在win+R即命令提示符中输入命令行的。但是命令行的结构我们必须知道: d15b8b728875e2a59011377afb995f0.png

Node.js的编码注意事项

这里必须要提一嘴,Node.js是不能使用BOM和DOM的API的,看下面两张图就能理解:

1aa38a3730f20bd8388a84546896564.png

be5b06596d12296132d6ee754a4252e.png

从上面两张图可以看出,两者API之间是有共同点的,即console定时器。而且,在Node.js中的顶级对象不是window,而是global

console.log(globalThis === global);  //true

Buffer

什么是Buffer

什么是Buffer,用官方的解释就是:他是一个类似于Array的对象,用于表达固定长度的字节序列。说白了,就是一段固定长度的内存空间,用于处理二进制数据。

说多了也没用,我举了一个最简单的例子,直接看一下就OK:

里面的alloc就是分配的意思,里面的参数则为分配一个10字节的缓冲区,而一个字节则为8比特。allocUnsafealloc不同的则是前者会使用之前使用过的空间,因此可能会有旧的数据,而后者则会完全创建一个新的缓冲区来使用。.from方法则是将10进制的数据转换为了8进制并存储在了缓冲区里面。

fs模块

fs模块的全称是file system,它的主要操作很多,我们一一举例即可。

写入文件以及同步和异步

写入文件分为两步,第一步就是先导入fs模块,第二步则就是写入操作了。

let fs = require('fs');
//如果下面要写入的文件不存在则会先优先创建一个。
fs.writeFile('座右铭.txt','三人行',err => {
    if (err) {
        console.log("失败");
        return;
    }
    console.log("成功");
})
console.log("异步情况下,我是先打印的");

注意啦,fs.write(file,data,{option},callBack),上面的情况是异步的操作,如果为同步的话,需要将fs.write()更改为fs.writeSync()。但是由于同步是不需要回调函数的,但是我们可以通过trycatch来环绕。

let fs = require('fs');
try {
    fs.writeFile('座右铭.txt','三人行');
    console.log("成功");
} catch (error) {
    console.log("失败");
}
console.log("异步情况下,我是先打印的");

文件的追加写入

追加写入有两种方案,我们先说第一种——fs.appendFile,这个具体代码的样式其实是和fs.writeFile差不多的,我们看代码:

let fs = require('fs');
fs.appendFile('座右铭.txt',`\r\n新加的一块内容`,err => {
    if (err) {
        console.log("异步失败了");
        return;
    }
    console.log("异步成功了");
})

fs.appendFileSync('座右铭.txt','\r\n再来一个新行');

我们还可以使用fs.write()进行追加,具体细节主要是第三个参数,里面的flag则是文件打开时的行为,值为'a'则是append的缩写,即追加行为,看例子吧:

let fs = require('fs');
fs.writeFile('座右铭.txt','\r\n再来一个',{flag:'a'},err => {
    if (err) {
        console.log("失败");
        return;
    }
    console.log("成功");
});

文件流式写入

文件流式写入跟上述是差不多的,第一步也是先导入fs模块,然后创建一个文件写入流对象,最后进行操作即可。看代码示例吧:

let fs = require('fs');

const Fs = fs.createWriteStream('观后感.txt');
Fs.write(`1\r\n`);
Fs.write(`2\r\n`);
Fs.write(`3\r\n`);
Fs.write(`4\r\n`);

//资源写入完毕,通道也会自动关闭的。
Fs.close();

文件读取

文件读取也是如此,先导入fs模块,然后调用fs.readFile()方法即可。

let fs = require('fs');

fs.readFile('观后感.txt',(err,data)=>{
    if (err) {
        console.log("打印失败");
        return;
    }
    //里面的data数据是Buffer形式的,因此我们需要将其转换为utf-8形式方便阅读。
    console.log(data.toString());
})

文件流式读取

这个同上面的文件流式写入是差不多的,这个需要绑定事件,代码如下:

let fs = require('fs');

const stream = fs.createReadStream('观后感.txt');

stream.on('data',chunk=>{
    console.log(chunk.toString());
});

stream.on('end',chunk=>{
    console.log("读取成功");
})

文件复制

文件的复制操作,这里我使用的是流式操作,我们先流式读取,然后再流式写入,这样子边读取边写入就使得效率非常的高,代码:

let fs = require('fs');

let fr = fs.createReadStream('观后感.txt');

let fw = fs.createWriteStream('观后感2.txt');

fr.on('data',chunk=>{
    fw.write(chunk);
})

文件重命名和移动

文件重命名和移动使用的则都是fs.rename,使用起来非常简单,直接看代码:

let fs = require('fs');
//下面是文件的重命名
fs.rename('更改前的.txt','更改后的.txt',err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
})
//下面是文件的移动
fs.rename('更改前的.txt','../资料/更改前的.txt',err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
})

文件删除

文件删除就更简单了,fs.unlinkfs.rm,因为都是异步,因此都需要使用回调函数,例子:

let fs = require('fs');

fs.unlink('更改前的.txt',err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
})

fs.rm('更改前的.txt',err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
})

文件夹的操作

创建文件夹则为:fs.mkdir,删除的话也使用fs.rm,这里注意的是,如果递归操作则需要写入第二个参数{recursive:true},代码:

let fs = require('fs');

fs.mkdir('./a/b/c',{recursive:true},err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
});

fs.rm('./a',{recursive:true},err=>{
    if (err) {
        console.log("fail");
        return;
    }
    console.log("win");
})

查看资源的状态

196f1e1f1c75b39608cd5c5368a4458.png

相对路径的Bug与解决

这个应该是fs模块里面最难的一个点了,我们需要知道,例如执行命令:fs.writeFileSync(./index.html,'内容')。这个相对的路径的参照物其实是命令行的工作目录。但是我们有个全局变量——_dirname,这个则是所在文件的所在目录的绝对路径,因此,我们一般写绝对路径都是在执行的文件前加上_dirname的。

对于最基本的fs模块其实就这些,具体的可能还有path模块,但是我们先了解了这些基础即可。