前言
因为nodejs是模块化的开发,它有许多的模块也有许许多多的方法需要我们花费时间去学习。下面我将介绍一些比较常用的模块以及模块的一些基本操作,希望和我一样是初学者的伙伴们可以一起学习:)
更完整的内容大家可以进入nodejs的中文网查看API文档进行全面的学习!
nodejs中文网:
http://nodejs.cn/
fs(文件系统)
fs
模块可用于与文件系统进行交互(以类似于标准 POSIX 函数的方式)。
要使用此模块:
const fs = require('fs');
所有的文件系统操作都具有同步的、回调的、以及基于 promise 的形式。
fs.mkdir(path[, options], callback)
- path <string> | <Buffer> | <URL>
- options <Object> | <integer>
- recursive <boolean> 默认值: false。
- mode <string> | <integer> 在 Windows 上不支持。默认值: 0o777。
- callback <Function>
- err <Error>
异步地创建目录。
回调会传入可能的异常、以及创建的第一个目录的路径(如果 recursive
为 true
), (err, [path]
)。
可选的 options
参数可以是整数(指定 mode
(权限和粘滞位))、或对象(具有 mode
属性和 recursive
属性(指示是否要创建父目录))。 当 path
是已存在的目录时,调用 fs.mkdir()
仅在 recursive
为 false 时才会导致错误。
// 创建 `/目录1/目录2/目录3`,不管 `/目录1` 和 `/目录1/目录2` 是否存在。
fs.mkdir('/目录1/目录2/目录3', { recursive: true }, (err) => {
if (err) throw err;
});
在 Windows 上,对根目录使用 fs.mkdir()
(即使使用遍历)也会导致错误:
fs.mkdir('/', { recursive: true }, (err) => {
// => [Error: EPERM: operation not permitted, mkdir 'C:\']
});
path(路径)
path
模块提供了一些实用工具,用于处理文件和目录的路径。 可以使用以下方式访问它:
const path = require('path');
path.join([…paths])
...paths
<string> 路径片段的序列。- 返回: <string>
path.join()
方法会将所有给定的 path
片段连接到一起(使用平台特定的分隔符作为定界符),然后规范化生成的路径。
长度为零的 path
片段会被忽略。 如果连接后的路径字符串为长度为零的字符串,则返回 '.'
,表示当前工作目录。
path.join('/目录1', '目录2', '目录3/目录4', '目录5', '..');
// 返回: '/目录1/目录2/目录3/目录4'
path.join('目录1', {}, '目录2');
// 抛出 'TypeError: Path must be a string. Received {}'
如果任何的路径片段不是字符串,则抛出 TypeError
。
目录操作(fs&&path)
// require() 导入模块
// 导入 路径操作模块
const path = require('path');
// 导入文件操作系统 模块
const fs = require('fs');
// 文件操作 案例
// 初始化目录结构
// img css js index.html
// 创建项目 存储的 目录地址
let root = 'H:\\01-NodeJSCore\\20200920Day01\\02-授课源码';
let initData = {
projectName: 'mydemo',
data: [
{ name: 'img', type: 'dir' },
{ name: 'css', type: 'dir' },
{ name: 'js', type: 'dir' },
{name:'index.html',type:'file'}
]
}
// 创建 项目的 根路径
// fs.mkdir(path.join('H:\\01-NodeJSCore\\20200920Day01\\02-授课源码','mydemo'))
fs.mkdir(path.join(root, initData.projectName), (err) => {
if (err) { // 出错 直接终止程序
return;
}
})
let fileContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
`;
// 创建子目录和文件
initData.data.forEach((item) => {
// console.log(item);
if (item.type == 'dir') {
// console.log('===');
// 创建子目录
// fs.mkdirSync(path.join(root, initData.projectName, item.name));
} else if (item.type == 'file') {
// 创建文件 并写入 内容(html页面的基本结构)
fs.writeFileSync(path.join(root,initData.projectName,item.name),fileContent)
}
})
Buffer(缓冲器)
Buffer
对象用于表示固定长度的字节序列。 许多 Node.js API 都支持 Buffer
。
Buffer
类是 JavaScript 的 Uint8Array 类的子类,且继承时带上了涵盖额外用例的方法。 只要支持 Buffer
的地方,Node.js API 都可以接受普通的 Uint8Array。
Buffer
类在全局作用域中,因此无需使用 require('buffer').Buffer
。
Buffer.alloc(size[, fill[, encoding]])
size
<integer> 新Buffer
的所需长度。fill
<string> | <Buffer> | <Uint8Array> | <integer> 用于预填充新Buffer
的值。默认值:0
。encoding
<string> 如果fill
是一个字符串,则这是它的字符编码。默认值:'utf8'
。
分配一个大小为size
字节的新Buffer
。 如果 fill 为undefined
,则用零填充Buffer
。
const buf = Buffer.alloc(5);
console.log(buf);
// 打印: <Buffer 00 00 00 00 00>
如果 size
大于 buffer.constants.MAX_LENGTH 或小于 0,则抛出 ERR_INVALID_OPT_VALUE。
如果指定了 fill
,则分配的 Buffer
通过调用 buf.fill(fill) 进行初始化。
const buf = Buffer.alloc(5, 'a');
console.log(buf);
// 打印: <Buffer 61 61 61 61 61>
如果同时指定了 fill
和 encoding
,则分配的 Buffer
通过调用 buf.fill(fill, encoding)
进行初始化 。
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
console.log(buf);
// 打印: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
调用 Buffer.alloc()
可能比替代的 Buffer.allocUnsafe()
慢得多,但能确保新创建的 Buffer
实例的内容永远不会包含来自先前分配的敏感数据,包括可能尚未分配给 Buffer
的数据。
如果 size
不是一个数字,则抛出 TypeError
。
Buffer.concat(list[, totalLength])
list
<Buffer[ ]> | <Uint8Array[ ]> 要合并的Buffer
数组或 Uint8Array 数组。totalLength
<integer> 合并后list
中的Buffer
实例的总长度。- 返回: <Buffer>
返回一个合并了 list 中所有 Buffer 实例的新 Buffer。
如果 list
中没有元素、或 totalLength
为 0,则返回一个长度为 0 的 Buffer
。
如果没有提供 totalLength
,则通过将 list
中的 Buffer
实例的长度相加来计算得出。
如果提供了 totalLength
,则会强制转换为无符号整数。 如果 list
中的 Buffer
合并后的总长度大于 totalLength
,则结果会被截断到 totalLength
的长度。
// 用含有三个 `Buffer` 实例的数组创建一个单一的 `Buffer`。
const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(14);
const buf3 = Buffer.alloc(18);
const totalLength = buf1.length + buf2.length + buf3.length;
console.log(totalLength);
// 打印: 42
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
console.log(bufA);
// 打印: <Buffer 00 00 00 00 ...>
console.log(bufA.length);
// 打印: 42
一些方法:
// Buffer模块 缓冲流 字节数组
/**
* Buffer的基本操作 : Buffer本质就是 字节数组
* 1, 构造方法
* 2, 静态方法
* 3, 实例方法
*/
// 实例化 buffer对象
// let buf = new Buffer(5); 定义buffer数组长度的方法 不推荐了
// console.log(buf); 返回 16进制的结果 并且 该结果 是随机产生的5个 字节
// 5表示的是 buffer的长度
// let buf = Buffer.alloc(5);
// console.log(buf); <Buffer 00 00 00 00 00> 返回16进制的结果
// let buf = Buffer.from('hello'); // <Buffer 68 65 6c 6c 6f> 返回 16进制
// console.log(buf);
// let buf = Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
// console.log(buf.toString());
// let buf = Buffer.from('hello');
// console.log(Buffer.isBuffer(buf)); true
// console.log(Buffer.isBuffer({})); false
// 注意: utf-8 的编码格式: 一个汉字 三个字节 所以为 6
// let buf = Buffer.from('中国');
// console.log(buf);
// console.log(Buffer.byteLength(buf)); 返回6
// console.log(buf.toString());
// let buf = Buffer.from('中国', 'ascii');
// console.log(buf) 返回为2 一个字节 就是一个字符
// console.log(buf.toString()); 对于汉字 不允许 使用这种编码 以上 并不表示 中国 这两个字符
// 功能方法:
// (1)Buffer.isEncoding() 判断是否 支持 该编码
// (2)Buffer.isBuffer() 判断是否 为Buffer
// (3)Buffer.byteLength() 返回执行 编码的字节长度 默认为 utf-8
// (4)Buffer.concat() 将一组 Buffer对象合并为 一个Buffer对象
// let buf1 = Buffer.alloc(3);
// let buf2 = Buffer.alloc(5);
// let buf3 = Buffer.concat([buf1, buf2])
// console.log(Buffer.byteLength(buf3)); // 8
// let buf1 = Buffer.from('tom');
// let buf2 = Buffer.from('jerry');
// let buf3 = Buffer.concat([buf1, buf2])
// console.log(Buffer.byteLength(buf3));
// console.log(buf3.toString());
// 实例方法
// let buf = Buffer.alloc(5);
// buf.write('hello', 2, 3);
// console.log(buf)
// console.log(buf.toString());
// let buf = Buffer.from('hello');
// let buf1 = buf.slice();
// // console.log(buf==buf1); false 只要是对象 那么存储的地址 就是不同
// // console.log(buf===buf1); false
// console.log(buf1);
// let buf = Buffer.from('hello');
// let buf1 = buf.slice(2,8);
// console.log(buf1.toString());
// JSON.stringify() 该方法 转换为 json格式的字符串
// const buf = Buffer.from('hello');
// // {"type":"Buffer","data":[104,101,108,108,111]} 转换为10进制的数据
// const json = JSON.stringify(buf); // 最终转换为 JSON格式的字符串
// console.log(json);
url(URL)
url
模块用于处理与解析 URL。 使用方法如下:
const url = require('url');
querystring(查询字符串)
querystring
模块提供用于解析和格式化 URL 查询字符串的实用工具。 可以使用以下方式访问它:
const querystring = require('querystring');
http(HTTP)
若要使用 HTTP 服务器和客户端,则可以 require('http')
。
Node.js 中的 HTTP 接口旨在支持许多传统上难以使用的协议的特性。 特别是,大块的(且可能是块编码的)消息。 接口永远不会缓冲整个请求或响应,所以用户可以流式地传输数据。
HTTP 消息头由类似如下的对象表示:
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }
键是小写的。 值还未被修改。
为了支持所有可能的 HTTP 应用程序,Node.js 的 HTTP API 都是非常底层的。 它仅进行流处理和消息解析。 它将消息解析为消息头和消息主体,但不会解析具体的消息头或消息主体。
接收到的原始消息头保存在 rawHeaders
属性中,该属性是 [key, value, key2, value2, ...]
的数组。 例如,上面的消息头对象可能具有的 rawHeaders
列表如下所示:
[ 'ConTent-Length', '123456',
'content-LENGTH', '123',
'content-type', 'text/plain',
'CONNECTION', 'keep-alive',
'Host', 'mysite.com',
'accepT', '*/*' ]