通过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:
1
2
3
4
5
6let fs = require("fs");
```
### 同步文件的读写
- 打开文件
```js
fs.openSync(path, flags)- path:要打开文件的路径
- flags:打开文件要做的操作的类型
- r(只读)、w(可写)、a(追加)
- 返回值:返回一个文件的描述符作为结果
- 示例:
1
let fd = fs.openSync("hello.txt" , "w");
向文件中写入内容
1
fs.writeFileSync(file, data[, options])
- fd:文件的描述符,需要传递要写入的文件的描述符
- string:要写入的内容
- position:写入的起始位置
- encoding:写入的编码,默认utf-8(不传)
- 示例:
1
fs.writeSync(fd , "今天天气真不错", 2);
读取文件
1
fs.readFileSync(path[, options])
- readFileSync: read的高度封装
- path: 文件地址
- options: 配置参数,传对象
- 示例:
1
fs.readFileSync("文件地址", {flag: 'r', encoding: "utf-8"})
保存并关闭文件
1
fs.closeSync(fd)
- 示例:
1
fs.closeSync(fd);
- 示例:
删除文件
1
fs.unlink('路径', callback)
异步文件读写(推荐)
打开文件
1
fs.open(path, flags, callback)
- callback:当写入完成以后执行的函数
- err:错误对象,如果没有错误则为null
- data:文件内容
- callback:当写入完成以后执行的函数
写入文件
1
fs.writeFile(file, data[, options], callback)
读取文件
1
fs.readFile(path[, options], callback)
关闭文件
1
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}
流式文件读写
适用于一些比较大的文件
创建一个写入流
1
fs.createWriteStream(path[, options])
- 示例:
1
let ws = fs.createWriteStream("hello3.txt", {flag: "w", encoding: 'utf-8'});
- 示例:
创建一个读取流
1
fs.createReadStream(path[, options])
- 监听流的关闭中,当数据读取完要先调用关闭流ws.end();
- 示例:
1
let rs = fs.createReadStream("hello3.txt", {flag: "a", encoding: 'utf-8'})
通过监听流的open、ready和close事件来监听流的打开、准备和关闭状态
- on(事件字符串,回调函数)
- 可以为对象绑定一个事件
- once(事件字符串,回调函数)
- 可以为对象绑定一个一次性的事件,该事件将会在触发一次以后自动失效
- 流打开
1
ws.once("open",function () {});
- 流关闭
1
ws.once("close",function () {ws.end()});
- on(事件字符串,回调函数)
向文件中写入内容
1
ws.write("内容",callback)
关闭流
1
ws.end(callback)
- 如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,data事件绑定完毕,它会自动开始读取数据
- 示例:
1
2
3
4
5
6rs.on("data", function (data) {
// 读取数据
console.log(data)
//将读取到的数据写入到可写流中,相当于复制文件,写入的文件要和读取的文件类型一样
ws.write(data);
});
pipe()可以将可读流中的内容,直接输出到可写流中
1
rs.pipe(ws)
- 是上面代码的封装
目录
- 读取目录
1
fs.readdir(path,callback)
1
2
3
4
5
6
7
8
9
10
11
12
13
14fsReadDir = () => {
fs.readdir("..../fs", (err, files) => {
// files 是一个包含该目录所有文件的数组
if(!err) {
// 通过循环将该命令下的文件全部追加到txtPath文件下
files.forEach(async (filename,i) => {
let content = await fsRead('目录的路径/' + filename)
await fsWrite (txtPath, content)
})
} else {
console.log(err)
}
})
} - 删除目录
1
fs.rmdir(path,callback)
输入和输出
- 引入readline
1
let readline = require('readline')
- 创建readline接口实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14let r1 = readline.createInterface({
output: process.stdout,
input: process.stdin
})
// 设置r1,提问事件
r1.question("问题:", (answer) => {
console.log("答复:"+ answer)
r1.close()
})
r1.on('close', () => {
process.exit(0)
}) - 封装一个函数,用于初始化和创建package.json的程序
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46let readline = require('readline')
let { fsWrite } = require('路径')
let r1 = readline.createInterface({
output: process.stdout,
input: process.stdin
})
// 封装一个提问函数
const lxQuestion = (question: string) => {
return new Promise((resolve, reject) => {
r1.question(question + ":", (answer) => {
resolve(answer)
r1.close()
})
})
}
// 创建包的提问问题函数
const createPackage = async () => {
let name = await lxQuestion("你的包名是什么?")
let anthor = await lxQuestion("你的作者是什么?")
let main = await lxQuestion("你的主文件是什么?")
let desc = await lxQuestion("你的描述是什么?")
let version = await lxQuestion("你的版本是什么?")
// 将内容写入package.json文件中
let content = `{
"name": "${name}",
"version": "${version}",
"description": "${desc}",
"scripts": {
"dev": "webpack serve --config config/webpack.dev.js",
"build": "webpack --config config/webpack.prd.js",
"test": "echo Error: no test specified && exit 1"
},
"keywords": [],
"author": "${main}",
"license": "ISC",
"dependencies": {},
"devDependencies": {}
}`
await fsWrite('package.json',content)
r1.close()
}
createPackage()
r1.on('close', () => {
process.exit(0)
})