banner
banner
banner
NEWS LETTER

Node的文件系统(File System)

Scroll down

通过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.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
    6
    rs.on("data", function (data) {
    // 读取数据
    console.log(data)
    //将读取到的数据写入到可写流中,相当于复制文件,写入的文件要和读取的文件类型一样
    ws.write(data);
    });

pipe()可以将可读流中的内容,直接输出到可写流中 — rs.pipe(ws)

  • 是上面代码的封装

目录

读取目录 — fs.readdir(path,callback)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fsReadDir = () => {
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)
}
})
}

删除目录 — fs.rmdir(path,callback)

输入和输出

引入readline — let readline = require('readline')

创建readline接口实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let 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
46
let 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)
})
其他文章
cover
爬虫总结
  • 24/10/31
  • 17:15
  • Node
cover
Node基础
  • 24/10/31
  • 17:15
  • Node
目录导航 置顶
  1. 1. Buffer(缓冲区)
    1. 1.1. 作用
    2. 1.2. 结构存储
    3. 1.3. Buffer的方法
  2. 2. fs模块 — 用来操作系统中的文件
    1. 2.1. 同步文件的读写
    2. 2.2. 异步文件读写(推荐)
    3. 2.3. 流式文件读写
    4. 2.4. 目录
    5. 2.5. 输入和输出
请输入关键词进行搜索