当前位置:   article > 正文

Node.js超详细教程!_node.js教程 pdf

node.js教程 pdf

0. 基础概念

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,使用了一个事件驱动、非阻塞式 I/O 模型,让 JavaScript 运行在服务端的开发平台。

官方地址:https://nodejs.org/en

中文地址:https://nodejs.org/zh-cn

代码初体验:

  1. console.log("hello NodeJS")
  2. // 1.进入到对应 js 文件的目录下
  3. // 2.执行 node 1-hello.js
  4. // 3.输出:hello NodeJS
示例代码地址: https://github.com/chenyl8848/node.js-study

1. Buffer

1.1 概念

Buffer 是一个类似于数组的对象,用于表示固定长度的字节序列。Buffer 本质是一段内存空间,专门用来处理二进制数据。

1.2 特点

  • Buffer 大小固定且无法调整
  • Buffer 性能较好,可以直接对计算机内存进行操作
  • 每个元素的大小为 1 字节(byte)

1.3 使用

1.3.1 Buffer 的创建

Node.js 中创建 Buffer 的方式主要如下几种:

Buffer.alloc

  1. // 创建了一个长度为 10 字节的 Buffer,相当于申请了 10 字节的内存空间,每个字节的值为 0
  2. // 结果为 <Buffer 00 00 00 00 00 00 00 00 00 00>
  3. let buf_1 = Buffer.alloc(10);

Buffer.allocUnsafe

  1. // 创建了一个长度为 10 字节的 Buffer,Buffer 中可能存在旧的数据, 可能会影响执行结果,所以叫 unsafe
  2. let buf_2 = Buffer.allocUnsafe(10);

Buffer.from

  1. // 通过字符串创建 Buffer
  2. let buf_3 = Buffer.from('hello');
  3. // 通过数组创建 Buffer
  4. let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);

1.3.2 Buffer 与字符串的转化

可以借助 toString 方法将 Buffer 转为字符串

  1. // buffer 与字符串的转换
  2. const buffer = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);
  3. // 默认使用 UTF-8 的编码格式
  4. console.log(buffer.toString())
注意:toString 默认是按照 utf-8 编码方式进行转换的。

1.3.3 Buffer 的操作

Buffer 可以直接通过 [] 的方式对数据进行处理。

  1. const buffer = Buffer.from('hello');
  2. // 二进制:1101000
  3. console.log(buffer[0].toString(2))
  4. // 修改 buffer
  5. buffer[0] = 95
  6. console.log(buffer.toString())
  7. // 溢出 如果修改的数值超过 255 ,则超过 8 位数据会被舍弃
  8. const buffer = Buffer.from('hello')
  9. // 会舍弃高位的数字,因为八位的二进制最高值为 255 0001 0110 1001 => 0110 1001
  10. buffer[0] = 361
  11. console.log(buffer)
  12. // 中文 一个 utf-8 的字符 一般 占 3 个字节
  13. const buffer = Buffer.from('你好')
  14. console.log(buffer)
注意:
如果修改的数值超过255,则超过8位数据会被舍弃 一个 utf-8 的字符一般占3个字节

2. fs 模块

fs 全称为 file system,称之为文件系统,是 Node.js 中的内置模块,可以对计算机中的磁盘进行操作。

2.1 文件写入

文件写入就是将数据保存到文件中,有如下的 API

方法 说明
writeFile 异步写入
writeFileSync 同步写入
appendFile/appendFileSync 追加写入
createWriteStream 流式写入

2.1.1 异步写入

语法: fs.writeFile(file, data, [options], callback)

参数说明:

  • file:文件名
  • data:待写入的数据
  • options:选项设置 (可选)
  • callback:写入回调

返回值: undefined

代码示例:

  1. // 1.导入 fs 模块
  2. const fs = require('fs')
  3. // 2.写入文件
  4. // writeFile 异步写入,四个参数:1.文件路径 2.写入内容 3.配置信息 4.回调函数
  5. // 文件写入成功
  6. fs.writeFile('./座右铭.txt', '封狼居胥,禅于姑衍,饮马瀚海', error => {
  7. // errror 为 null就是写入成功
  8. if (error) {
  9. console.log('文件写入失败')
  10. return;
  11. }
  12. console.log('文件写入成功')
  13. });

2.1.2 同步写入

语法: fs.writeFileSync(file, data, [options]) 参数说明:

  • file:文件名
  • data:待写入的数据
  • options:选项设置 (可选) 返回值: undefined 代码示例:
  1. // 1.导入 fs 模块
  2. const fs = require('fs')
  3. // 2.写入文件
  4. // 同步写入,没有回调函数
  5. fs.writeFileSync('./座右铭.txt', '封狼居胥,禅于姑衍,饮马瀚海,燕石勒然')
Node.js 中的磁盘操作是由其他线程完成的,结果的处理有两种模式:
同步处理:JavaScript 主线程会等待其他线程的执行结果,然后再继续执行主线程的代码,效率较低
异步处理:JavaScript 主线程不会等待其他线程的执行结果,直接执行后续的主线程代码,效率较好

2.1.3 追加写入

appendFile 作用是在文件尾部追加内容,appendFile 语法与 writeFile 语法完全相同

语法:

  • fs.appendFile(file, data, [options], callback)
  • fs.appendFileSync(file, data, [options])

返回值: 二者都为 undefined

代码示例:

  1. // 1.引入 fs 模块
  2. const fs = require('fs');
  3. const content = '\r\n但使龙城飞将在,不教胡马度阴山';
  4. // fs.appendFile('./座右铭.txt', content, error => {
  5. // // errror 为 null就是写入成功
  6. // if (error) {
  7. // console.log('文件追加写入失败')
  8. // return;
  9. // }
  10. // console.log('文件追加写入成功');
  11. // })
  12. // 同步文件追加写入
  13. // fs.appendFileSync('./座右铭.txt', content)
  14. // 使用 writeFile 的方式追加文件写入
  15. fs.writeFile('./座右铭.txt', content, {flag: 'a'}, error => {
  16. if (error) {
  17. console.log('文件追加写入失败')
  18. return;
  19. }
  20. console.log('文件追加写入成功')
  21. })
  22. console.log('hello world')

2.1.4 流式写入

语法: fs.createWriteStream(path, [options])

参数说明:

  • path:文件路径
  • options:选项配置( 可选 )

返回值: Object

代码示例:

  1. // 1.导入 fs 模块
  2. const fs = require('fs');
  3. // 2.创建写入流对象
  4. const writeStream = fs.createWriteStream('./观书有感.txt');
  5. // 3.写入内容
  6. writeStream.write('半亩方塘一鉴开\r\n')
  7. writeStream.write('天光云影共徘徊\r\n')
  8. writeStream.write('问渠那得清如许\r\n')
  9. writeStream.write('为有源头活水来\r\n')
  10. // 4.关闭通道 不是必须
  11. // writeStream.close();
程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数。
流式写入方式适用于大文件写入或者频繁写入的场景, writeFile 适合于写入频率较低的场景。

2.2 文件读取

文件读取顾名思义,就是通过程序从文件中取出其中的数据,有如下几种 API:

方法 说明
readFile 异步读取
readFileSync 同步读取
createReadStream 流式读取

2.2.1 异步读取

语法: fs.readFile(path, [options], callback)

参数说明:

  • path:文件路径
  • options:选项配置
  • callback:回调函数

返回值: undefined

代码示例:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.异步读取
  4. fs.readFile('./座右铭.txt', (error, data) => {
  5. if (error) {
  6. console.log('文件读取错误')
  7. return
  8. }
  9. console.log(data.toString())
  10. })

2.2.2 同步读取

语法: fs.readFileSync(path, [options])

参数说明:

  • path:文件路径
  • options:选项配置

返回值: string | Buffer

代码示例:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.同步读取
  4. let data = fs.readFileSync('./座右铭.txt');
  5. console.log(data.toString())

2.2.3 流式读取

语法: fs.createReadStream(path, [options])

参数说明:

  • path:文件路径
  • options:选项配置(可选)

返回值:Object

代码示例:

  1. // 1.导入 fs 模块
  2. const fs = require('fs')
  3. // 2.创建读取流对象
  4. const rs = fs.createReadStream('./观书有感.txt');
  5. // 3.绑定 data 事件
  6. rs.on('data', chunk => {
  7. // chunk:块儿、大块儿
  8. console.log(chunk)
  9. console.log(chunk.length)
  10. console.log(chunk.toString())
  11. })
  12. // 4.结束事件(可选)
  13. rs.on('end', () => {
  14. console.log('文件读取完成')
  15. })

2.3 文件移动与重命名

在 Node.js 中,可以使用 rename 或 renameSync 来移动或重命名文件或文件夹

语法:

  • fs.rename(oldPath, newPath, callback)
  • fs.renameSync(oldPath, newPath)

参数说明:

  • oldPath:文件当前的路径
  • newPath:文件新的路径
  • callback:操作后的回调

代码示例:

  1. // 1.导入 fs 模块
  2. const fs = require('fs');
  3. // 2.文件重命名
  4. // fs.rename('./座右铭-2.txt', './西汉名将.txt', error => {
  5. // if (error) {
  6. // console.log('文件重命名失败')
  7. // return ;
  8. // }
  9. // console.log('文件重命名成功')
  10. // })
  11. // 3.文件移动
  12. // 文件夹如果不存在,会报错误 Error: ENOENT: no such file or directory
  13. fs.rename('./西汉名将.txt', './文件/西汉名将.txt', error => {
  14. if (error) {
  15. console.log(error, '移动文件出错');
  16. return ;
  17. }
  18. console.log('操作成功')
  19. })

2.4 文件删除

在 Node.js 中,可以使用 unlink 或 unlinkSync 或 rm 或 rmSync 来删除文件

语法:

  • fs.unlink(path, callback)
  • fs.unlinkSync(path)

参数说明:

  • path:文件路径
  • callback:操作后的回调

代码示例:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.调用 unlink 方法
  4. // unlinkSync:同步删除
  5. // fs.unlink('./座右铭-3.txt', error => {
  6. // if (error) {
  7. // console.log('删除文件错误', error)
  8. // return;
  9. // }
  10. // console.log('删除文件成功')
  11. // })
  12. // 3.调用 rm 方法
  13. // rmSync:同步删除
  14. fs.rm('./文件/西汉名将.txt', error => {
  15. if (error) {
  16. console.log('文件删除失败', error)
  17. return;
  18. }
  19. console.log('文件删除成功')
  20. })

2.5 文件夹操作

在 Node.js 中可以通过如下 API 对文件夹进行创建、读取、删除等操作

方法 说明
mkdir / mkdirSync 创建文件夹
readdir / readdirSync 读取文件夹
rmdir / rmdirSync 删除文件夹

2.5.1 创建文件夹

在 Node.js 中,可以使用 mkdir 或 mkdirSync 来创建文件夹

语法:

  • fs.mkdir(path, [options], callback)
  • fs.mkdirSync(path, [options])

参数说明:

  • path:文件夹路径
  • options:选项配置(可选)
  • callback:操作后的回调

示例代码:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.创建文件夹
  4. // mkdir make:制作 directory:目录
  5. fs.mkdir('./html', error => {
  6. if (error) {
  7. console.log('创建目录失败', error)
  8. return;
  9. }
  10. console.log('创建目录成功')
  11. })
  12. // 3.递归创建文件夹
  13. fs.mkdir('./a/b/c', {
  14. recursive: true
  15. }, error => {
  16. if (error) {
  17. console.log("递归创建文件夹失败", error)
  18. return;
  19. }
  20. console.log('递归创建文件夹成功')
  21. })
  22. // 4.递归同步创建文件夹
  23. fs.mkdirSync('./a/b/c', {recursive: true});

2.5.2 读取文件夹

在 Node.js 中,可以使用 readdir 或 readdirSync 来读取文件夹

语法:

  • fs.readdir(path, [options], callback)
  • fs.readdirSync(path, [options])

参数说明:

  • path:文件夹路径
  • options:选项配置(可选)
  • callback:操作后的回调

示例代码:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.读取文件夹
  4. // readdir read:读取 dir:directory 目录
  5. fs.readdir('./', (error, data) => {
  6. if (error) {
  7. console.log('读取文件夹错误', error)
  8. return;
  9. }
  10. // [
  11. // '1-文件写入.js',
  12. // '2-追加写入.js',
  13. // '3-流式写入.js',
  14. // '4-文件读取.js',
  15. // '5-流式读取.js',
  16. // '6-练习-文件复制.js',
  17. // '7-文件重命名与移动.js',
  18. // '8-删除文件.js',
  19. // '9-文件夹操作.js',
  20. // 'a',
  21. // 'html',
  22. // '座右铭.txt',
  23. // '文件',
  24. // '观书有感.txt'
  25. // ]
  26. console.log(data)
  27. })
  28. //同步读取
  29. // let data = fs.readdirSync('./');
  30. // console.log(data);

2.5.3 删除文件夹

在 Node.js 中,可以使用 rmdir 或 rmdirSync 来删除文件夹

语法:

  • fs.rmdir(path, [options], callback)
  • fs.rmdirSync(path, [options]) 参数说明:
  • path:文件夹路径
  • options:选项配置(可选)
  • callback:操作后的回调

示例代码:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.删除文件夹
  4. // fs.rmdir('./文件', error => {
  5. // if (error) {
  6. // console.log('删除文件夹失败', error)
  7. // return;
  8. // }
  9. // console.log('删除文件夹成功')
  10. // })
  11. // 3.递归删除文件夹
  12. // 递归删除文件夹失败 [Error: ENOTEMPTY: directory not empty, rmdir 'E:\JavaEE\frontend\nodejs-study\2-fs文件系统\a']
  13. // 不推荐使用
  14. // fs.rmdir('./a', {recursive: true}, error => {
  15. // if (error) {
  16. // console.log('递归删除文件夹失败', error)
  17. // return ;
  18. // }
  19. // console.log('递归删除文件夹成功')
  20. // })
  21. // 推荐使用
  22. fs.rm('./a', {recursive: true}, error => {
  23. if (error) {
  24. console.log('递归删除文件失败', error)
  25. return;
  26. }
  27. console.log('递归删除文件成功')
  28. })
  29. //同步递归删除文件夹
  30. fs.rmdirSync('./a', {recursive: true})

2.6 查看资源状态

在 Node.js 中,可以使用 stat 或 statSync 来查看资源的详细信息

语法:

  • fs.stat(path, [options], callback)
  • fs.statSync(path, [options])

参数说明:

  • path:文件夹路径
  • options:选项配置(可选)
  • callback:操作后的回调

示例代码:

  1. // 1.引入 fs 模块
  2. const fs = require('fs')
  3. // 2.stat 方法 status 的缩写:状态
  4. fs.stat('./观书有感.txt', (error, data) => {
  5. if (error) {
  6. console.log('操作失败', error)
  7. return;
  8. }
  9. // Stats {
  10. // dev: 985301708,
  11. // mode: 33206,
  12. // nlink: 1,
  13. // uid: 0,
  14. // gid: 0,
  15. // rdev: 0,
  16. // blksize: 4096,
  17. // ino: 281474979770305,
  18. // size: 92,
  19. // blocks: 0,
  20. // atimeMs: 1684373309132.9426,
  21. // mtimeMs: 1684289136772.1648,
  22. // ctimeMs: 1684289136772.1648,
  23. // birthtimeMs: 1684289136770.7136,
  24. // atime: 2023 - 05 - 18 T01: 28: 29.133 Z,
  25. // mtime: 2023 - 05 - 17 T02: 05: 36.772 Z,
  26. // ctime: 2023 - 05 - 17 T02: 05: 36.772 Z,
  27. // birthtime: 2023 - 05 - 17 T02: 05: 36.771 Z
  28. // }
  29. console.log(data)
  30. console.log(data.isFile())
  31. console.log(data.isDirectory())
  32. })
  33. // 3.同步获取状态
  34. let data = fs.statSync('./观书有感.txt');
  35. console.log(data)
  36. console.log(data.isFile())
  37. console.log(data.isDirectory())

结果值对象结构:

  • size:文件体积
  • birthtime:创建时间
  • mtime:最后修改时间
  • isFile:检测是否为文件
  • isDirectory:检测是否为文件夹

2.7 相对路径问题

fs 模块对资源进行操作时,路径的写法有两种:

  • 相对路径 ./座右铭.txt:当前目录下的座右铭.txt 座右铭.txt:等效于上面的写法 ../座右铭.txt:当前目录的上一级目录中的座右铭.txt
  • 绝对路径 D:/Program Files:windows 系统下的绝对路径 /usr/bin:Linux 系统下的绝对路径
相对路径中所谓的当前目录,指的是命令行的工作目录,而并非是文件的所在目录。所以当命令行的工作目录与文件所在目录不一致时,会出现一些 BUG。

2.8 __dirname

__dirname 与 require 类似,都是 Node.js 环境中的 '全局' 变量 __dirname 保存着当前文件所在目录的绝对路径,可以使用 __dirname 与文件名拼接成绝对路径

代码示例:

  1. let data = fs.readFileSync(__dirname + '/data.txt');
  2. console.log(data);
使用 fs 模块的时候,尽量使用 __dirname 将路径转化为绝对路径,这样可以避免相对路径产生的 Bug

2.9 练习

实现文件复制的功能

代码示例:

  1. /**
  2. * 需求:
  3. * 复制【座右铭.txt】
  4. */
  5. // 1.引入 fs 模块
  6. const fs = require('fs');
  7. // 全局对象,即 global 对象的属性,无须声明即可访问。它用于描述当前 Node 进程状态的对象,提供了一个与操作系统的简单接口。
  8. const process = require('process')
  9. // 方式一:使用 readFile
  10. // 2.读取文件
  11. // let data = fs.readFileSync('./座右铭.txt');
  12. // // 3.写入文件
  13. // fs.writeFileSync('./座右铭-2.txt', data);
  14. // // 查看系统耗费内存
  15. // // rss: 19795968 字节
  16. // console.log(process.memoryUsage())
  17. // 方式二:使用流式操作
  18. // 2.创建流式读取
  19. let rs = fs.createReadStream('./座右铭.txt');
  20. // 3.创建流式写入
  21. let ws = fs.createWriteStream('./座右铭-3.txt');
  22. // // 4.绑定 data 事件
  23. // rs.on('data', chunk => {
  24. // ws.write(chunk);
  25. // })
  26. // // 5.绑定 end 事件
  27. // rs.on('end', () => {
  28. // // rss: 20885504 字节 相比于同步的方式占用内存会比较小
  29. // console.log(process.memoryUsage())
  30. // })
  31. // 4.使用 pipe(管道) 可直接复制
  32. rs.pipe(ws)

3. path 模块

path 模块提供了操作路径的功能&#

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号