第18篇 rabbitmq ValueWriter源码分析

我们在创建Frame(数据帧)时候,需要将一些属性写入到Frame accumator中,也就是ByteArrayOutputStream中,我们首先熟悉一下ValueWriter类

  • 大概了解一下其实它对DataOutputStream一个封装,套一层

1、成员变量

  • 成员变量默认值描述
    final DataOutputStream对象输出流
    final int COPY_BUFFER_SIZE4096复制buffer大小

2、方法

方法名描述图示
ValueWriter(DataOutputStream out)构造函数
final void writeShortstr(String str)写short字符串1
final void writeLongstr(LongString str)写Long字符串2
final void writeLongstr(String str)写String, 采用utf-8编码,同时都是先写长度,后写内容
final void writeShort(int s)直接用的DataOutputStream的writeShort方法
final void writeLonglong(long ll)直接用的DataOutputStream的writeLong方法
final void writeTable(Map<String, Object> table)写一个map集合的值3
final void writeArray(List<?> value)写List集合的值
final write Octet(int octet)类型简写
final void writeTimestamp时间戳
void flush()flush的流中
  • table的大小,不同数据类型大小 (图1-2)
类型大小类型简写备注
String字节数组长度+1无简写map的key,(字符串采用utf-8转的)
String字节数组长度 + 4 + 1Smap的value (字符串采用utf-8转的)
LongString字节数组长度 + 4 + 1Smap的value
Integer4+1Imap的value
BigDecimal5+1Dmap的value
Date 或 Timestamp8+1Tmap的value
Map4+1+tableSize(map)Fmap的value (递归调用,tableSize方法)
Byte1+1bmap的value
Double8+1dmap的value
Float4+1fmap的value
Long8+1lmap的value
Short2+1smap的value
Boolean1+1tmap的value
byte[]4+1+字节数组长度xmap的value
List4+arraySize()Amap的value ,递归调用(具体类型)
Object[]4+arraySize()Amap的value,递归调用(具体类型)
null1Vmap的value

2.1、图示

  1. writeShortstr(String str)

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLWNwRVU-1623942575160)(/Users/liangchen/Library/Application%20Support/typora-user-images/image-20210617171357758.png)]
    • 总结
      1. 字符串采用utf-8进行字节编码
      2. 字节长度不能大于255,大于255就不是一个short范围,写出字节长度
      3. 写出具体字节内容
  2. writeLongstr(LongString str)

    • image-20210617203708676

    • 总结

      将LongString转换OutputStream流过程

      1. 写一个LongString的长度
      2. 将LongString 的InputStream 转换OutputStream
  3. writeTable(Map<String, Object> table)

    • image-20210617213317416

    • 总结

      • 对于有size和length的会写对应size或length
      • 每个类型都会与之对应类型简写,详情参看上图(图1-2)
      1. 确定map的大小(说字节大小),key和value都是String写长度是不一样的
      2. 对应规则参见(图1-2)进行累加
      3. 遍历key和value,写key值
      4. 然后写value的值
      5. value的值首先会先写一个类型简写,具体类型简写参看(图1-2)
      6. BigDecimal写入流的一个过程, 首先是简写类型,scale值, 去掉scale对值
      7. 写时间戳getTime()/1000也就秒
      8. 集合(List和Map)需要继续拆分成小元素(递归调用)

3、LongString 接口

  • 提供对LongString的访问的对象。这可以实现为直接从连接套接字读取,具体取决于要读取的内容的大小,长字符串可能包含多达4GB的内容

3.1、成员变量

  • 变量名默认值描述
    long MAX_LENGTH0xffffffffL字节(折算4Gib大小)

3.2、方法

  • 方法名描述
    long length()字节大小(0,MAX_LENGTH]
    DataInputStream getStream()获取内容流,可以重复调用此函数返回相同的流,可能不支持倒带
    byte[] getBytes()以字节数组的形式获取内容,这不必是副本,对返回数组的更新可能会更改字符串的值,重复调用此函数可能会返回相同的数组,如果此字符串的长度大于Integer.MAX_VALUE,则此函数将调用失败,并抛出IllegalStateException (大概2GIB样子),也就大于这个长度就用getStream获取数据
    String toString()把自己字节数组变成字符串

3.3、总结

  1. 让读取流可以重复读取
  2. 也可以通过字节数组获取数据(只是限制2GiB大小)主要由于Integer.MAX_VALUE

4、LongStringHelper 类

  • LongString的帮助类,内部定义ByteArrayLongString去实现LongString接口

4.1、内部类 ByteArrayLongString

4.1.1、成员变量
  • 变量名称默认值描述
    final byte[] bytes字节数组
4.1.2、方法
方法名描述
long length()字节大小bytes.length
DataInputStream getStream()new DataInputStream(new ByteArrayInputStream(bytes))
byte[] getBytes()bytes
String toString()new String(bytes, Charset.forName(“utf-8”))
ByteArrayLongString(byte[] byte)byte[] 入参构造方法
boolean equals(Object o)重写了equals方法,利用Arrays.equals(byte[] b1, byte[] b2)
in hashCode()重写了hashCode,使用Arrays.hashCode(byte[] b1)

4.2、LongStringHelper方法

方法名描述
LongString asLongString(String string)new ByteArrayLongString(string.getBytes(Charset.forName(“utf–8”)))
LongSring asLongString(byte[] bytes)new ByteArrayLongString(bytes)

4.3、总结

  1. 其实它最大4Gib限制没有体现,也就是目前没有其作用,不限制大小,这个其实需要看一下DataOutputStream是否有限制
  2. LongString目标其实就是就字符串和字节数组统一一下,同时具有可以重复读,其实每次都创建一个DateInputStream对象

5、总结

  1. 这个类主要约定好具体类型值怎么写,比如Integer,Long, List,Map之类
  2. 定义类型简写
  3. 定义一个标准字符串和字节数组封装的工具类,重复读取和方便使用(LongString)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值