主题
Buffer与Stream之间转换
buffer与stream的操作
1. buffer的常用API
js
/* 创建buffer */
let buf = new Buffer(10);
console.log(buf.length);//10
//nodejs中不建议使用new Buffer
// 创建一个长度为10字节的空buffer
let buf2 = Buffer.alloc(10);
//创建空间并且清空为0
console.log(buf2.length);//10
//buffer大小确定后不能修改,因为他直接操作底层内存
console.log(buf2[0].toString(16));
//转为十六进制输出
let buf3 = Buffer.allocUnsafe(10);
//创建空间但不清空buffer
/* buffer转换为json或string */
let buf4 = Buffer.from('你好') // 将字符串转换为json
console.log(buf4.toJSON()) // { type: 'Buffer', data: [ 228, 189, 160, 229, 165, 189 ] }
console.log(buf4.toString()) // 你好
console.log(buf4.length) // 6 一个中文占3字节
/* 拼接buffer */
let buf5 = Buffer.from('hello')
let buf6 = Buffer.from('word')
// Buffer有一个静态方法 concat,用于拼接多个buffer为一个
let buf7 = Buffer.concat([buf5,buf6])
console.log(buf7.toString()); // helloword
/* 缓冲区裁剪slice */
// slice参数:开始位置,结束位置
console.log(buf8.toString()); // ell
/* 缓冲区拷贝copy (不常用) */
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
2. stream常用
js
let fs = require("fs");
//创建可读流
let readF = fs.createReadStream("文件路径");
//创建可写流
let writeF = fs.createWriteStream("文件路径2");
readF.on("data",function(data){
//写入可写流
writeF.write(data);
});
//监听可读流关闭
readF.once("close",function(){
//关闭可写流
writeF.end();
});
//上面的方法太麻烦了所以。。。
readF.pipe(writeF);
//这句话表示上面的一片
3. 拷贝
js
const fs = require('fs')
let path = './index.html'
let target = './copy.html'
let read = fs.createReadStream(path)
let write = fs.createWriteStream(target)
read.pipe(write)
4. zip压缩
js
const http = require('http')
const fs = require('fs')
const zlib = require('zlib')
const htmlFilePath = './index.html'
http.createServer(
function (req, res) {
// res.writeHead(200, {"content-encoding": "gzip"})
fs.createReadStream(htmlFilePath)
// .pipe(zlib.createGzip())
.pipe(res)
}
).listen(8000)
http.createServer(
function (req, res) {
res.writeHead(200, {"content-encoding": "gzip"})
fs.createReadStream(htmlFilePath)
.pipe(zlib.createGzip())
.pipe(res)
}
).listen(8001)
压缩前 压缩后
5. stream 转 buffer
js
function streamToBuffer(stream) {
return new Promise((resolve, reject) => {
let buffers = [];
stream.on('error', reject);
stream.on('data', (data) => buffers.push(data))
stream.on('end', () => resolve(Buffer.concat(buffers))
});
}
6. buffer 转 stream
js
let Duplex = require('stream').Duplex;
function bufferToStream(buffer) {
let stream = new Duplex();
stream.push(buffer);
stream.push(null);
return stream;
}
7. buffer与stream互转
js
const fs = require('fs')
let Duplex = require('stream').Duplex;
let stream = new Duplex();
let b = new Buffer.from("hello")
stream.push(b);
stream.push(null);
console.log(b.toString()) // hello
let write = fs.createWriteStream('./copy2.js')
stream.pipe(write)
或者
js
var stream = require('stream');
// 创建一个bufferstream
var bufferStream = new stream.PassThrough();
//将Buffer写入
bufferStream.end(new Buffer('Test data.'));
//进一步使用
bufferStream.pipe(process.stdout)
8. Buffer 与字符编码
Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。
js
const buf = Buffer.from('runoob', 'ascii');
console.log(buf.toString('hex')); // 输出 72756e6f6f62
console.log(buf.toString('base64')); // 输出 cnVub29i
Node.js 目前支持的字符编码包括:
ascii
- 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。utf8
- 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。utf16le
- 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。ucs2
- utf16le 的别名。base64
- Base64 编码。latin1
- 一种把 Buffer 编码成一字节编码的字符串的方式。binary
- latin1 的别名。hex
- 将每个字节编码为两个十六进制字符。
9. buffer转换
Buffer对象可以与字符串之间相互转换,目前支持的字符串类型有如下几种: ASCII
、UFTF-8
、UTF-16LE/UCS-2
、Base64
、Binary
、Hex
1)字符串转Buffer
字符串转buffer主要是通过构造函数完成的:
js
new Buffer(str, [encoding])
通过构造函数转换的Buffer对象,存储的只是一种编码类型,encoding参数不传递时,默认按照utf-8编码进行转码和存储。
一个Buffer内存储不同编码内容 若一个Buffer对象内,要存储不同编码的内容,可以通过write()
方法实现:
js
buf.write(str, [offset], [length], [encoding])
注意: 由于可以不断写入内容到buffer对象中,并且每次写入可以指定编码,所以buffer对象中可以存储多种编码转化后的内容,需要小心的是,由于各种编码所用字节长度不同,将buffer反转回字符串时候需要谨慎处理。
2)Buffer转字符串
Buffer对象有一个toString()
方法,可以将Buffer对象转换为字符串
js
buf.toString([encoding], [start], [end])
encoding
不传默认为utf-8 start
、end
可以指定局部转换还是全部转换,若buffer对象由多种编码写入,就需要在局部指定不同编码,才能转换回正常的编码。
3)Buffer不支持的编码类型
目前,Node的Buffer对象支持的编码类型有限,只有少数的几种编码类型可以在字符串和Buffer之间转换,为此,Buffer对象提供一个isEncoding()
函数来判断编码是否支持转换。
js
Buffer.isEncoding(encoding) // 传入encoding(编码)会输出true/false,true表示支持转换,反之。
但是,GBK,GB2312、BIG-5都不支持转换。 若要转换,有两个第三方模块iconv
和iconv-live
都可以支持更多编码类型的转换,包括Windows 125系列,IOS-8859系列,IBM/DOS代码页系列,等等。。 其中iconv-live
由纯js编写,iconv
则由c++
调用libiconv库完成,性能不如iconv