7.Buffer知识点

什么是Buffer?

  1. 缓冲区Buffer是暂时存放输入输出数据的一段内存。
  2. Buffer是十六进制。
  3. JS语言没有二进制数据类型,而在处理TCP和文件流的时候,必须要处理二进制数据。所以,其实我们的node是把数据从二进制转换成了十六进制
  4. NodeJS提供了一个Buffer对象来提供对二进制数据的操作
  5. Buffer是一个表示固定内存分配的全局对象,也就是说要放到缓存区中的字节要提前确定
  6. Buffer好比由一个多位字节元素组成的数组,可以有效地在javascript中表示二进制数据
什么是字节
  • 1字节 = 8位
  • 1k = 1024字节
  • 1个汉字(utf8下) = 3字节 = 24位
  • 1个字节转化成十进制是255(因为一个字节8位,每个位都是1的时候,转成十进制是255)
  • 1个字节转换成十六进制是ff

定义Buffer的方式

  • 一定要先定义好大小
  • buffer是16进制的
  • 定义的方式
    • 通过长度定义buffer

      • 注意:下面的alloc的中文意思是“分配”
      var buffer = Buffer.alloc(6);//长度为6个字节的buffer,先清空内存,再开辟6个字节的buffer,这种方法比较耗性能
      var buffer = Buffer.allocUnsafe(6);//不安全的,上一次内存不清空,直接开辟6个字节的buffer
      console.log(buffer);
      console.log(buffer.length);//6
      
    • 通过数组转换成buffer

      	//将一个数组转换成buffer
      	var buffer = Buffer.from([1,2,3,16,255]);
      	console.log(buffer);//<Buffer 01 02 03 10 ff>,其实就是把上面每个元素转换成十六进制
      	//注意:数组每个元素最大是255,转换成buffer(16进制)是ff,如果越界,就会对255取模,比如256,则转成buffer就是01
      	//如果是字符串,也不行,会转成00
      	console.log(buffer.length);//5
      
    • 通过字符串转换成buffer

      	//将一个字符串转换成buffer
      	var buffer = Buffer.from('壮壮小伙');
      	console.log(buffer);//<Buffer e5 a3 ae e5 a3 ae e5 b0 8f e4 bc 99>  一个汉字,三个字节,所以总共有12个16进制
      	console.log(buffer.length);//12
      
    • 注意,转换成buffer后,length就是buffer的长度了
      - buffer的其他方法

    • buffer.fill方法,填充buffer中的内容

      	//fill方法
      	var buffer = Buffer.allocUnsafe(10);
      	buffer.fill(0xff);
      	console.log(buffer);//<Buffer ff ff ff ff ff ff ff ff ff ff> 填充的是16进制,那就是16进制
      	buffer.fill(23);
      	console.log(buffer);//<Buffer 17 17 17 17 17 17 17 17 17 17> 填充10进制,转换成16进制
      
    • buffer.toString()方法,将buffer转化成字符串

      	var buffer = Buffer.from('壮壮小伙');
      	console.log(buffer.toString());//'壮壮小伙'
      
    • buffer.slice方法,截取想要的buffer

      • 与数组一样,浅拷贝,存在引用关系
    • buffer.copy方法,拷贝buffer

      • 重点,常用
      • 语法:源Buffer.copy(目标Buffer,目标起始,源起始,源结束);
        • 其中结束为止不包括源结束,跟slice(1,2)一样,不包括2
      • 原理:先开辟大小,然后一个个拷贝进新开辟的Buffer
      var zz1 = Buffer.from('壮壮');
      var zz2 = Buffer.from('小伙');
      //Buffer不能改变大小,不能push,但可以如下:
      //先定义大小
      var zz = Buffer.allocUnsafe(12);//1个汉字三个字节
      //拷贝buffer
      zz1.copy(zz,0);//参数有四个,分别为:目标Buffer,目标起始,源起始,源结束(不包括)
      zz2.copy(zz,6);
      console.log(zz.toString());//'壮壮小伙'
      
    • Buffer.concat方法,buffer的拼接方法

      • 重点,常用
      //concat 链接buffer
      var zz = Buffer.concat([zz1,zz2]);//两个参数,分别为:list(数组),totalLength
      console.log(zz.toString());//'壮壮小伙'
      
      • 自己手写一个Buffer.concat方法
      Buffer.concat = function(list,totalLength){
      	//1. 判断长度是否传递,如果传递了用传的,没传自己算一个总长度
      
      	//2. 通过长度创建一个这么大的buffer,使用Buffer.alloc(长度)
      
      	//3. 再循环list,将每一项拷贝到这个大buffer上,使用buffer.copy
      
      	//4. 如果长度过长,可以用fill将过长的部分填充为空,或者可以使用slice截取有效长度
      
      	//5. 返回一个新buffer
      
      	//1
      	if(typeof totalLength === 'undefined'){
      		totalLength = list.reduce((prev,next) => prev + next.length,0);
      	}
      
      	//2
      	let buffer = Buffer.alloc(totalLength);
      
      	//3
      	let offset = 0;
      	list.forEach(buff => {
      		//判断是否为buffer
      		if(!Buffer.isBuffer(buff)){
      			return throw error('not buffer');
      		}
      		buff.copy(buffer,offset);
      		offset += buff.length;
      	})
      
      	//4
      	return buffer.slice(0,offset);
      }
      
    • Buffer.isBuffer,判断是否是buffer类型

      • Buffer.isBuffer(buff),返回boolean

自己手写一个Buffer.concat方法

···js
Buffer.concat = function(list,totalLength){
//1. 判断长度是否传递,如果传递了用传的,没传自己算一个总长度

//2. 通过长度创建一个这么大的buffer,使用Buffer.alloc(长度)

//3. 再循环list,将每一项拷贝到这个大buffer上,使用buffer.copy

//4. 如果长度过长,可以用fill将过长的部分填充为空,或者可以使用slice截取有效长度

//5. 返回一个新buffer

//1
if(typeof totalLength === 'undefined'){
	totalLength = list.reduce((prev,next) => prev + next.length,0);
}

//2
let buffer = Buffer.alloc(totalLength);

//3
let offset = 0;
list.forEach(buff => {
	if(!Buffer.isBuffer(buff)){
		return throw error('not buffer');
	}
	buff.copy(buffer,offset);
	offset += buff.length;
})

//4
return buffer.slice(0,offset);

}
···

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,文件操作是处理文本或二进制数据输入输出的基础。以下是一些关键的文件操作知识点: 1. 文件类型:主要有两种文件类型,文本文件(`FILE *`)和二进制文件(`fopen()`函数可指定为`"rb"`、`"wb"`等模式)。 2. 文件打开:使用`fopen()`函数打开文件,它返回指向`FILE`类型的指针,如果成功则为非NULL,失败则为NULL。 ```c FILE *fp = fopen("filename", "r/w/a+b"); ``` 3. 文件关闭:用`fclose()`函数关闭已经打开的文件,释放资源。 ```c fclose(fp); ``` 4. 读写操作:`fread()`用于从文件读取数据,`fwrite()`用于向文件写入数据。还有`getc()`和`putc()`用于字符读写。 ```c char buffer[100]; fread(buffer, sizeof(char), 100, fp); // 读取100个字符 fwrite(buffer, sizeof(char), 100, fp); // 写入100个字符 ``` 5. 文件位置控制:`fseek()`用于移动文件指针,`ftell()`获取当前文件位置。 ```c fseek(fp, 10, SEEK_SET); // 移动到第10个字节位置 long pos = ftell(fp); // 获取当前位置 ``` 6. 文件状态:`feof()`检查是否达到文件末尾,`ferror()`检查是否有错误发生。 ```c if (feof(fp)) { // 文件已到达末尾 } if (ferror(fp)) { // 发生错误 } ``` 7. 文件预处理:`#include <stdio.h>`包含标准输入输出头文件,`<fstream>`头文件用于C++的文件操作。 8. 错误处理:使用`perror()`输出错误信息,或者定义`errno`全局变量检查错误代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值