通过Node来操作系统中的文件
使用文件系统,需要先引入fs模块,fs是核心模块,直接引入不需要下载
运行文件: node 文件名带后缀
Buffer(缓冲区)
作用
- 专门存储二进制的数据
- 在内存空间开辟出固定大小的内存,一旦确定,则不能修改
- 效率高
结构存储
- Buffer的结构和数组很像,操作的方法也和数组类似
- 在buffer中存储的都是二进制数据,但是在显示时都是以16进制的形式显示
- buffer中每一个元素的范围是从00 - ff,一个元素,占用内存的一个字节
- 8bit = 1Byte(字节)
- 1024Byte = 1KB
- 1024KB = 1MB
- 1024MB = 1GB
- 1024GB = 1TB
Buffer的方法
- Buffer.from(str) — 将字符串转成buffer对象
- buf.toString() — 将buffer对象转成字符串
- buf.length — 占用内存的大小
- str.length — 字符串的长度
- Buffer.alloc(size) — 创建一个指定大小的buffer
- Buffer.allocUnsafe(size) — 创建一个指定大小的buffer,但是可能含有敏感数据,效率高,内存泄漏
- 通过索引,来操作buf中的元素 — buf2[1] = 255;
fs模块 — 用来操作系统中的文件
fs模块中的大部分操作都提供了两种方法,同步(带sync)和异步(有回调)
- 引入fs: let fs = require(“fs”);
同步文件的读写
打开文件 — fs.openSync(path, flags)
- path:要打开文件的路径
- flags:打开文件要做的操作的类型
- r(只读)、w(可写)、a(追加)
- 返回值:返回一个文件的描述符作为结果
- 示例:let fd = fs.openSync(“hello.txt” , “w”);
向文件中写入内容 — fs.writeFileSync(file, data[, options])
- fd:文件的描述符,需要传递要写入的文件的描述符
- string:要写入的内容
- position:写入的起始位置
- encoding:写入的编码,默认utf-8(不传)
- 示例:fs.writeSync(fd , “今天天气真不错”, 2);
读取文件 — fs.readFileSync(path[, options])
- readFileSync: read的高度封装
- path: 文件地址
- options: 配置参数,传对象
- 示例:fs.readFileSync(“文件地址”, {flag: ‘r’, encoding: “utf-8”})
保存并关闭文件 — fs.closeSync(fd)
- 示例:fs.closeSync(fd);
删除文件 — fs.unlink('路径', callback)
异步文件读写(推荐)
打开文件 — fs.open(path, flags, callback)
- callback:当写入完成以后执行的函数
- err:错误对象,如果没有错误则为null
- data:文件内容
写入文件 — fs.writeFile(file, data[, options], callback)
读取文件 — fs.readFile(path[, options], callback)
关闭文件 — fs.close(fd, callback)
- 想要直接使用读取文件返回的文件名字来打开相同名字的文件,需要去除左右两边的空白符trim()
- 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// 封装读取的操作
const fsRead = (url: string) => {
return new Promise((resolve, reject) => {
fs.readFile(url, {flag: 'r', encoding: "utf-8"}, (err, data) => {
if(!err) {
resolve(data)
} else {
reject(err)
}
})
})
}
fsRead("文件地址").then((res) => console.log(res))
// 封装写入的操作
const fsWrite = (url: string, data: any) => {
return new Promise((resolve, reject) => {
fs.writeFile(url, data, {flag: 'a', encoding: 'utf-8' }, (err) => {
if(!err) {
resolve()
} else {
reject(err)
}
})
})
}
module.exports = {fsRead, fsWrite}
流式文件读写
适用于一些比较大的文件
创建一个写入流 — fs.createWriteStream(path[, options])
- 示例:let ws = fs.createWriteStream(“hello3.txt”, {flag: “w”, encoding: ‘utf-8’});
创建一个读取流 — fs.createReadStream(path[, options])
- 监听流的关闭中,当数据读取完要先调用关闭流ws.end();
- 示例:let rs = fs.createReadStream(“hello3.txt”, {flag: “a”, encoding: ‘utf-8’})
通过监听流的open、ready和close事件来监听流的打开、准备和关闭状态
- on(事件字符串,回调函数)
- 可以为对象绑定一个事件
- once(事件字符串,回调函数)
- 可以为对象绑定一个一次性的事件,该事件将会在触发一次以后自动失效
- 流打开 — ws.once(“open”,function () {});
- 流关闭 — ws.once(“close”,function () {ws.end()});
向文件中写入内容 — ws.write("内容",callback)
关闭流 — ws.end(callback)
- 如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,data事件绑定完毕,它会自动开始读取数据
- 示例:
1
2
3
4
5
6rs.on("data", function (data) {
// 读取数据
console.log(data)
//将读取到的数据写入到可写流中,相当于复制文件,写入的文件要和读取的文件类型一样
ws.write(data);
});
pipe()可以将可读流中的内容,直接输出到可写流中 — rs.pipe(ws)
- 是上面代码的封装
目录
读取目录 — fs.readdir(path,callback)
1 | fsReadDir = () => { |
删除目录 — fs.rmdir(path,callback)
输入和输出
引入readline — let readline = require('readline')
创建readline接口实例
1 | let r1 = readline.createInterface({ |
- 封装一个函数,用于初始化和创建package.json的程序
1 | let readline = require('readline') |