# Buffer 缓存区和 path 路径
# Buffer 缓存区
Buffer 是 NodeJs 全局对象上的一个类(js Uint8Array 类的子类),是一个专门用于存储字节数据的类。NodeJs 提供了操作计算机底层的 API,而计算机底层只能识别 0 和 1,所以就提供了一个专门用于存储字节数据的 Buffer 类。
# Buffer 的创建
Buffer.alloc(size[, fill[, encoding]])
表示创建一个指定大小的缓冲区,可以给它指定填充 Buffer 的值以及编码。
const buf1 = Buffer.alloc(5);
console.log(buf1); // 打印: <Buffer 00 00 00 00 00>。存的是二进制,但console打印时会自动转换为16进制
const buf2 = Buffer.alloc(5, "a");
console.log(buf2); // 打印: <Buffer 61 61 61 61 61>
const buf3 = Buffer.alloc(11, "aGVsbG8gd29ybGQ=", "base64");
console.log(buf3); // 打印: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
2
3
4
5
6
7
8
Buffer.from(xxx)
将xxx
转换为二进制数据然后存储到缓冲区里。xxx
可以是字符串可以是对象也可以是一个 Buffer。
// 创建包含字符串 'buffer' 的 UTF-8 字节的新缓冲区。
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;
// 与 `arr` 共享内存。
const buf2 = Buffer.from(arr.buffer);
const buf3 = Buffer.from(Buffer.from("buffer"));
const buf4 = Buffer.from(new String("this is a test"));
const buf5 = Buffer.from("this is a tést");
2
3
4
5
6
7
8
9
10
11
12
13
14
# buf.toString()
buf.toString([encoding[, start[, end]]])
将 Buffer 中的二进制数据转换为字符串。start
开始解码的字节偏移量,end
停止解码的字节偏移量。
const buf1 = Buffer.allocUnsafe(26);
for (let i = 0; i < 26; i++) {
// 97 是 'a' 的十进制 ASCII 值。
buf1[i] = i + 97;
}
console.log(buf1.toString("utf8")); // 打印: abcdefghijklmnopqrstuvwxyz
console.log(buf1.toString("utf8", 0, 5)); // 打印: abcde
2
3
4
5
6
7
8
9
# buf.write()
buf.write(string[, offset[, length]][, encoding])
向 Buffer 里写入数据。
const buf = Buffer.alloc(5);
console.log(buf); // <Buffer 00 00 00 00 00>
// buf.write('abcdefg');
buf.write("abcdefg", 2, 2);
console.log(buf); // <Buffer 00 00 61 62 00>,偏移的是Buffer中的位置,所以前两个是00 00
console.log(buf.toString()); // ab
2
3
4
5
6
# buf.slice()
buf.slice([start[, end]])
截取 Buffer,从start
到end
const buf = Buffer.from("abcdefg");
const buf2 = buf.slice();
console.log(buf2); // <Buffer 61 62 63 64 65 66 67>
const buf3 = buf.slice(2);
console.log(buf3); // <Buffer 63 64 65 66 67>
const buf4 = buf.slice(2, 4);
console.log(buf4); // <Buffer 63 64>
2
3
4
5
6
7
# Buffer.isEncoding()
Buffer.isEncoding(encoding)
检查 Buffer 支持的编码。
console.log(Buffer.isEncoding("utf-8")); // 打印: true
console.log(Buffer.isEncoding("hex")); // 打印: true
console.log(Buffer.isEncoding("utf/8")); // 打印: false
console.log(Buffer.isEncoding("")); // 打印: false
2
3
4
# Buffer.isBuffer()
Buffer.isBuffer(obj)
检查是否是 Buffer 类型对象
Buffer.isBuffer(Buffer.alloc(10)); // true
Buffer.isBuffer(Buffer.from("foo")); // true
Buffer.isBuffer("a string"); // false
Buffer.isBuffer([]); // false
Buffer.isBuffer(new Uint8Array(1024)); // false
2
3
4
5
# Buffer.byteLength
Buffer.byteLength(string[, encoding])
获取 Buffer 实际字节长度。一个汉字占用三字节。
const buf = Buffer.from("123");
const buf2 = Buffer.from("你好");
console.log(buf.length); // 3
console.log(Buffer.byteLength(buf)); // 6,一个汉字占用三字节
console.log(buf2.length); // 3
console.log(Buffer.byteLength(buf2)); // 6,一个汉字占用三字节
2
3
4
5
6
# Buffer.concat
Buffer.concat(list[, totalLength])
拼接多个 Buffer。
const buf = Buffer.from("123");
const buf2 = Buffer.from("你好");
const buf3 = Buffer.from("abc");
const buf4 = Buffer.concat([buf, buf2, buf3]);
console.log(buf4); // <Buffer 31 32 33 e4 bd a0 e5 a5 bd 61 62 63>
console.log(buf4.toString()); // 123你好abc
2
3
4
5
6
# path 传输路径
path 模块提供了用于处理文件和目录的路径的实用工具
# path.basename()
path.basename()
方法返回 path 的最后一部分。ext
为可选的文件扩展名
path.basename("/foo/bar/baz/asdf/quux.html"); // 返回: 'quux.html'
path.basename("/foo/bar/baz/asdf/quux.html", ".html"); // 返回: 'quux'
2
# path.dirname()
ath.dirname(path)
方法返回 path 的目录名
path.dirname("/foo/bar/baz/asdf/quux"); // 返回: '/foo/bar/baz/asdf'
# path.extname()
path.extname(path)
方法返回 path 的扩展名
path.extname("index.html"); // 返回: '.html'
path.extname("index.coffee.md"); // 返回: '.md'
path.extname("index."); // 返回: '.'
path.extname("index"); // 返回: ''
path.extname(".index"); // 返回: ''
path.extname(".index.md"); // 返回: '.md'
2
3
4
5
6
# path.isAbsolute()
path.isAbsolute(path)
方法确定 path 是否为绝对路径。
// POSIX
path.isAbsolute("/foo/bar"); // true
path.isAbsolute("/baz/.."); // true
path.isAbsolute("qux/"); // false
path.isAbsolute("."); // false
// windows
path.isAbsolute("//server"); // true
path.isAbsolute("\\\\server"); // true
path.isAbsolute("C:/foo/.."); // true
path.isAbsolute("C:\\foo\\.."); // true
path.isAbsolute("bar\\baz"); // false
path.isAbsolute("bar/baz"); // false
path.isAbsolute("."); // false
2
3
4
5
6
7
8
9
10
11
12
13
# path.sep 和 path.delimiter
path.sep
提供特定于平台的路径片段分隔符。Windows 上是\
,POSIX 上是 /
path.delimiter
提供特定于平台的路径定界符。;
用于 Windows,:
用于 POSIX
console.log(process.env.PATH);
// 打印: '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'
process.env.PATH.split(path.delimiter);
// 返回: ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
2
3
4
5
# path.parse()和 path.format()
path.parse(path)
用于将 path 转换为对象。
在 POSIX 上:
┌─────────────────────┬────────────┐
│ dir │ base │
├──────┬ ├──────┬─────┤
│ root │ │ name │ ext │
" / home/user/dir / file .txt "
└──────┴──────────────┴──────┴─────┘
2
3
4
5
6
path.parse("/home/user/dir/file.txt");
// 返回:
// { root: '/',
// dir: '/home/user/dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file' }
2
3
4
5
6
7
在 Windows 上:
┌─────────────────────┬────────────┐
│ dir │ base │
├──────┬ ├──────┬─────┤
│ root │ │ name │ ext │
" C:\ path\dir \ file .txt "
└──────┴──────────────┴──────┴─────┘
2
3
4
5
6
path.parse("C:\\path\\dir\\file.txt");
// 返回:
// { root: 'C:\\',
// dir: 'C:\\path\\dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file' }
2
3
4
5
6
7
path.format(pathObject)
用于将对象转换成 path。
当向 pathObject 提供属性时,存在一个属性优先于另一个属性的组合:
- 如果提供 pathObject.dir,则忽略 pathObject.root
- 如果 pathObject.base 存在,则忽略 pathObject.ext 和 pathObject.name
在 POSIX 上:
// 如果提供 `dir`、`root` 和 `base`,
// 则将返回 `${dir}${path.sep}${base}`。
// `root` 将被忽略。
path.format({
root: "/ignored",
dir: "/home/user/dir",
base: "file.txt",
});
// 返回: '/home/user/dir/file.txt'
// 如果未指定 `dir`,则将使用 `root`。
// 如果仅提供 `root` 或 `dir` 等于 `root`,则将不包括平台分隔符。
// `ext` 将被忽略。
path.format({
root: "/",
base: "file.txt",
ext: "ignored",
});
// 返回: '/file.txt'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
在 Windows 上:
path.format({
dir: "C:\\path\\dir",
base: "file.txt",
});
// 返回: 'C:\\path\\dir\\file.txt'
2
3
4
5
# path.join()
path.join([...paths])
方法使用特定于平台的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
// 如果参数中没有添加/,那么该方法会自动添加
path.join("/foo", "bar", "baz/asdf", "quux", "..");
// 返回: '/foo/bar/baz/asdf'
// 如果参数中有..,那么会自动根据前面的参数生成的路径,去到上一级路径
path.join("/a/b", "/c", "../");
// 返回: '/a/b'
2
3
4
5
6
7
# path.normalize()
path.normalize(path)
方法规范化给定的 path,解析 '..' 和 '.' 片段。
path.normalize("/a//b///c////d/////index.html");
// 返回\a\b\c\d\index.html
path.normalize("C:\\temp\\\\foo\\bar\\..\\");
// 返回: 'C:\\temp\\foo\\'
path.win32.normalize("C:////temp\\\\/\\/\\/foo/bar");
// 返回: 'C:\\temp\\foo\\bar'
2
3
4
5
6
# path.relative()
path.relative(from, to)
计算相对路径
// 根据第一个参数找到第二个参数的相对路径
path.relative("/data/orandea/test/aaa", "/data/orandea/impl/bbb");
// 返回: '../../impl/bbb'
path.relative("C:\\orandea\\test\\aaa", "C:\\orandea\\impl\\bbb");
// 返回: '..\\..\\impl\\bbb'
2
3
4
5
# path.resolve()
path.resolve([...paths])
方法将路径或路径片段的序列解析为绝对路径。如果没有传入 path 片段,则 path.resolve() 将返回当前工作目录的绝对路径。
path.resolve("/foo/bar", "./baz");
// 返回: '/foo/bar/baz'
// 给定的路径序列从右到左处理,每个后续的 path 会被追加到前面,直到构建绝对路径。
path.resolve("/foo", "/bar", "baz");
// 返回: /bar/baz
// 生成的路径被规范化,并删除尾部斜杠(除非路径解析为根目录)。
path.resolve("/foo/bar", "/tmp/file/");
// 返回: '/tmp/file'
// 给定的路径序列从右到左处理,每个后续的 path 会被追加到前面,直到构建绝对路径。
// 如果在处理完所有给定的 path 片段之后,还没有生成绝对路径,则使用当前工作目录
path.resolve("wwwroot", "static_files/png/", "../gif/image.gif");
// 如果当前工作目录是 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16