Buffer和Stream
Buffer
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。
因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。
原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
1.Buffer对象
Buffer对象类似于数组,它的元素为16进制的两位数,即0到255的数值。示例代码如下:
var str = "深入浅出node.js";
var buf = new Buffer(str, 'utf-8');
console.log(buf);
//<Buffer e6 b7 b1 e5 85 a5 e6 b5 85 e5 87 ba 6e 6f 64 65 2e 6a 73>
上述中的中文字在UTF-8编码下占用3个元素,其余各占用一个元素。
2.字符串转换Buffer
字符串转Buffer对项主要是通过构造函数完成的:new Buffer(str,[encoding]);
通过构造函数转换的Buffer对象,存储的只能是一种编码类型。encoding 参数不传参时,默认按utf-8编码进行转码。
3.Buffer转字符串
Buffer对象的toString()可以将Buffer对象转换为字符串:buf.toString([encoding], [start], [end]);
可以设置encoding(默认为utf-8),start ,end这3个参数实现整体或者局部的转换。
Stream
流是一种抽象的数据结构。想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地到达另一个地方(例如洗手池)。
我们也可以把数据看成是数据流,比如你敲键盘的时候,就可以把每个字符依次连起来,看成字符流。
这个流是从键盘输入到应用程序,实际上它还对应着一个名字:标准输入流(stdin)。
Node.js中Stream 有四种流类型:
Readable - 可读操作。
Writable - 可写操作。
Duplex - 可读可写操作.
Transform - 操作被写入数据,然后读出结果。
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
data - 当有数据可读时触发。
end - 没有更多的数据可读时触发。
error - 在接收和写入过程中发生错误时触发。
finish - 所有数据已被写入到底层系统时触发。
读取型:
对数据流进行一次性读取:
readstream1.js
'use strict';
//引入fs模块
var fs = require('fs'); // 创建一个流:
var rs = fs.createReadStream(__dirname+'/sample.txt', 'utf-8');
var data=""; //data事件表示流的数据已经可以读取,此时一次性进行读取。
rs.on('data', function (chunk) {
console.log('Data')
console.log(chunk);
data+=chunk;
}); //end事件表示这个流已经到末尾,无数据可以读取。
rs.on('end', function () {
console.log('End');
console.log(data);
}); //error事件表示出错了。
rs.on('error', function (err) {
console.log('ERROR: ' + err);
});
26 console.log('程序执行完毕');
当对流进行切割,即限制读取长度,此时将会出现乱码,为避免乱码出现,将采用以下方式进行流操作:
readstream2.js
'use strict';
//引入fs模块
var fs = require('fs'); // 创建一个流,将文件可读流的每次读取的Buffer长度限制为11:
var rs = fs.createReadStream(__dirname+'/sample.txt',{highWaterMark: 11});
var chunks = [];
var size = 0;
var i=1; //data事件表示流的数据已经可以读取,此时将进行多次读取,需要将流进行连接。
rs.on('data', function (chunk) {
console.log('Data读取第'+i+++'次');
chunks.push(chunk);
size += chunk.length;
}); //end事件表示这个流已经到末尾,无数据可以读取。
rs.on('end', function () {
console.log('End');
//Buffer.concat()方法封装了从小Buffer对象向大Buffer对象的复制过程。
let buf =Buffer.concat(chunks, size);
console.log(buf);
let str = buf.toString('utf-8');
console.log(str);
}); //error事件表示出错了。
rs.on('error', function (err) {
console.log('ERROR: ' + err);
});
参数使用说明如下:
fd - 通过 fs.open() 方法返回的文件描述符。
buffer - 数据写入的缓冲区。
offset - 缓冲区写入的写入偏移量。
length - 要从文件中读取的字节数。
position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。
readfile.js
var fs = require('fs');
var buffer = new Buffer(1024); //设置缓冲区 console.log('即将打开文件');
fs.open(__dirname+'/sample.txt', 'r+', function (err, fd) {
if (err) {
console.error(err);
}
console.log('文件打开成功'); //fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd, buffer, 0, buffer.length, 0, function (err, bytes) { if (err) {
console.log(err);
}
console.log(bytes + "字节被读取:"); // 仅输出读取的字节
if (bytes > 0) {
console.log(buffer.slice(0, bytes).toString());
} //关闭文件
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("文件关闭成功");
});
})
})
写入型:
writestream.js
'use strict'; //引入fs模块
var fs = require('fs'); //写入文本数据
var ws1 = fs.createWriteStream(__dirname+'/output1.txt', 'utf-8');
//写数据
ws1.write('使用Stream写入文本数据...\n');
ws1.write('END.');
// 标记文件末尾
ws1.end();
// 处理流事件 --> data, end, and error
ws1.on('finish',function(){
console.log('写入完成');
});
ws1.on('error', function(err){
console.log(err.stack);
}); //写入二进制数据
var ws2 = fs.createWriteStream(__dirname+'/output2.txt');
ws2.write(new Buffer('使用Stream写入二进制数据...\n', 'utf-8'));
ws2.write(new Buffer('END.', 'utf-8'));
ws2.end();
ws2.on('finish',function(){
console.log('写入完成');
});
ws2.on('error', function(err){
console.log(err.stack);
}); console.log("程序执行完毕");
注:该模块的更多使用方法:http://www.runoob.com/nodejs/nodejs-fs.html
Buffer和Stream的更多相关文章
- 理解 nodeJS 中的 buffer,stream
在Node.js开发中,当遇到 buffer,stream,和二进制数据处理时,你是否像我一样,总是感到困惑?这种感觉是否会让你认为不了解它们,以为它们不适合你,认为而这些是Node.js作者们的事情 ...
- 11慕课网《进击Node.js基础(一)》Buffer和Stream
Buffer 用来保存原始数据 (logo.png) 以下代码读取logo.png为buffer类型 然后将buffer转化为string,新建png 可以将字符串配置: data:image/png ...
- nodejs stream & buffer 互相转换
stream 转 buffer function streamToBuffer(stream) { return new Promise((resolve, reject) => { let b ...
- Node.js:Buffer浅谈
Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...
- IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换
/* * 用于实现 IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换的帮助类 */ using System;using System.IO;us ...
- Using Live555 to Stream Live Video from an IP camera connected to an H264 encoder
http://stackoverflow.com/questions/27279161/using-live555-to-stream-live-video-from-an-ip-camera-con ...
- 一个轻巧高效的多线程c++stream风格异步日志(一)
一个轻巧高效的多线程c++stream风格异步日志 一个轻巧高效的多线程c++stream风格异步日志 前言 功能需求 性能需求 Logger实现 LogStream类 Logger类 LogStre ...
- c# Stream to File的知识点
个人倾向使用File.WriteAllByte写入文件: //Stream to File MemoryStream ms=...Stream; ms.Position = ; byte[] buff ...
- 流Stream
System.IO 提供了一个抽象类Stream , Stream类 支持对字节的读写操作.所谓的“流”,指的是Stream,也就是所谓的一个文件区.这个文件区中存储着的信息可以是在内存中,也可以是在 ...
随机推荐
- CentOS7时间和日期的同步 (chrony和)
CentOS 6版本,使用 hwclock CentOS 7版本,使用timedatectl 1.基本概念 1.1 GMT,UTC,CST,DST时间 世界标准时间 整个地球分为二十四时区,每个时区都 ...
- HashMap的实现原理-----哈希讲解
哈希,英文名Hash.他就像是一个隔壁家的孩子一样,伴随着码工们的成长.听到他们的名字,我们都觉得很高大上. 在写程序的时候,一般我们都是这样被教育的:这个事情搞不定?用哈希呀! 在面试的时候,一般是 ...
- 深入理解char * ,char ** ,char a[ ] ,char *a[]
1.数组的本质 数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素. 2.指针 指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址.由于地址也 ...
- android:ems="10"是什么意思
android:ems = " 设置TextView或者Edittext的宽度为10个字符的宽度.当设置该属性后,控件显示的长度就为10个字符的长度,超出的部分将不显示. xml中 andr ...
- d3.select(this)不能用箭头函数
d3中典型的数据绑定片段 const items = svg.selectAll('g') .data(gdfs,(d)=> d.name); const enter = items.enter ...
- Codeforces 960D - Full Binary Tree Queries
960D - Full Binary Tree Queries 思路: 用move1[i]记录第i层第1种操作移动的个数(对这一层的个数取模) 用move2[i]记录第i层第2种操作移动的个数(对这一 ...
- 并发之ThreadLocal
ThreadLocal ThreadLocal 用一种存储变量与线程绑定的方式,在每个线程中用自己的 ThreadLocalMap 安全隔离变量,为解决多线程程序的并发问题提供了一种新的思路. 简 ...
- 如何启动iis(Internet 信息服务(IIS)管理器)
Internet 信息服务(IIS)管理器 启动 IIS 管理器1.从“开始”菜单,指向“管理工具”,然后单击“Internet 信息服务 (IIS) 管理器”. 从“运行”对话框启动 IIS 管理器 ...
- 恶意代码分析-使用apataDNS+inetsim模拟网络环境
准备工作 虚拟机安装: Win7 Ubuntu apateDNS 密码:wplo inetsim 密码:ghla 客户端Win7需要做的工作 安装apateDNS 服务器端Ubuntu需要做的工作 下 ...
- android -------- Data Binding的使用(二)
分享一下Data Binding在项目中一些常用的基础,点击事件和输入框的一些操作. DataBinding允许我们在xml中view的一些事件属性(如onClick等)中填写DataBinding表 ...