我们在创建Frame(数据帧)时候,需要将一些属性写入到Frame accumator中,也就是ByteArrayOutputStream中,我们首先熟悉一下ValueWriter类
- 大概了解一下其实它对DataOutputStream一个封装,套一层
文章目录
1、成员变量
-
成员变量 默认值 描述 final DataOutputStream 对象输出流 final int COPY_BUFFER_SIZE 4096 复制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 + 1 | S | map的value (字符串采用utf-8转的) |
LongString | 字节数组长度 + 4 + 1 | S | map的value |
Integer | 4+1 | I | map的value |
BigDecimal | 5+1 | D | map的value |
Date 或 Timestamp | 8+1 | T | map的value |
Map | 4+1+tableSize(map) | F | map的value (递归调用,tableSize方法) |
Byte | 1+1 | b | map的value |
Double | 8+1 | d | map的value |
Float | 4+1 | f | map的value |
Long | 8+1 | l | map的value |
Short | 2+1 | s | map的value |
Boolean | 1+1 | t | map的value |
byte[] | 4+1+字节数组长度 | x | map的value |
List | 4+arraySize() | A | map的value ,递归调用(具体类型) |
Object[] | 4+arraySize() | A | map的value,递归调用(具体类型) |
null | 1 | V | map的value |
2.1、图示
-
writeShortstr(String str)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLWNwRVU-1623942575160)(/Users/liangchen/Library/Application%20Support/typora-user-images/image-20210617171357758.png)]
- 总结
- 字符串采用utf-8进行字节编码
- 字节长度不能大于255,大于255就不是一个short范围,写出字节长度
- 写出具体字节内容
-
writeLongstr(LongString str)
-
-
总结
将LongString转换OutputStream流过程
- 写一个LongString的长度
- 将LongString 的InputStream 转换OutputStream
-
-
writeTable(Map<String, Object> table)
-
-
总结
- 对于有size和length的会写对应size或length
- 每个类型都会与之对应类型简写,详情参看上图(图1-2)
- 确定map的大小(说字节大小),key和value都是String写长度是不一样的
- 对应规则参见(图1-2)进行累加
- 遍历key和value,写key值
- 然后写value的值
- value的值首先会先写一个类型简写,具体类型简写参看(图1-2)
- BigDecimal写入流的一个过程, 首先是简写类型,scale值, 去掉scale对值
- 写时间戳getTime()/1000也就秒
- 集合(List和Map)需要继续拆分成小元素(递归调用)
-
3、LongString 接口
- 提供对LongString的访问的对象。这可以实现为直接从连接套接字读取,具体取决于要读取的内容的大小,长字符串可能包含多达4GB的内容
3.1、成员变量
-
变量名 默认值 描述 long MAX_LENGTH 0xffffffffL 字节(折算4Gib大小)
3.2、方法
-
方法名 描述 long length() 字节大小(0,MAX_LENGTH] DataInputStream getStream() 获取内容流,可以重复调用此函数返回相同的流,可能不支持倒带 byte[] getBytes() 以字节数组的形式获取内容,这不必是副本,对返回数组的更新可能会更改字符串的值,重复调用此函数可能会返回相同的数组,如果此字符串的长度大于Integer.MAX_VALUE,则此函数将调用失败,并抛出IllegalStateException (大概2GIB样子),也就大于这个长度就用getStream获取数据 String toString() 把自己字节数组变成字符串
3.3、总结
- 让读取流可以重复读取
- 也可以通过字节数组获取数据(只是限制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、总结
- 其实它最大4Gib限制没有体现,也就是目前没有其作用,不限制大小,这个其实需要看一下DataOutputStream是否有限制
- LongString目标其实就是就字符串和字节数组统一一下,同时具有可以重复读,其实每次都创建一个DateInputStream对象
5、总结
- 这个类主要约定好具体类型值怎么写,比如Integer,Long, List,Map之类
- 定义类型简写
- 定义一个标准字符串和字节数组封装的工具类,重复读取和方便使用(LongString)