PushbackInputStream

PushbackInputStream 是一个允许写入的读出流:不仅可以输出,也支持输入;

误解

关于 PushbackInputStream 最容易的一个误解就是可能认为此类的功能即是向前读和向后读。
实际上,此类如其名:pushback 即压入,写入。而非向后读这么简单。如图1, PushbackInputStream 应该是下一种实现方式

图1 PushbackInputStream 实现

实现原理

作出一个猜测,PushbackInputStream 为了实现写入和读出的双向功能,最简单的实现方式就是一次性先将流全部读到内存,维护一个流指针,这样就可以支持读和写的双重功能。显然这种方式不适合:流长度是末知的,一次性装入内存不现实。

流存储的位置程序不应该关心,无论其是否全部已装入内存,抑或是在磁盘上,还是在网络上,总可以使用系统调用 read 或 readn 往后读直到完全读出。原生的流所不支持的是 pushback 功能。所以 pushback 功能支持应该作为一个挂件式,修饰物的功能加之物,不应该与原来的流交织在一起:这也即是功能明确,也可以避免流的污染。

图2 PushbackInputStream 原理
实现原理:
1.PushbackInputStream 内含一个原生流对象(组合),用于顺序从流中读出。还包含一个缓冲区 buf,此 buf 用于接收 pushback 的内容:如果缓冲区中的有效位置不足,则抛出异常。
2.每次读入都优先读完 buf 区,再顺序往后读原生流的内容。
3.每次写入(push back) 与原生流毫无关系,直接压入 buf 区,如果位置不足则报错。
4.buf 维护一个 pos 表明下一次缓存中应该继续读的位置,如果为 0 表示缓存区是满的,如果为 buf.length 表示缓存区是空的。原理如图 3 所示。
5.注意于 buf 的实现,如果连续调用 unread 压入多个字节,如 a b,则 read 出的字节与此顺序相反,为:b a。如果调用一次 unread 压入一个字节数组,则读出的顺序与数组顺序一致。具体可以看 buf 的实现代码。

图3 PushbackInputStream 之 buf 原理

注意

1.如果没有往  PushbackInputStream 中压入内容,则 buf 一直为空,不会被使用。
2.PushbackInputStream 虽然也含有一个缓冲区,但也 BufferedInputStream 中的缓冲区含义不一样,前者的缓冲区用于接收外部写入的内容,后者的缓冲区用于接收内容。且前者是调用者手动压入,后者是程序自动装入。

root@yunxin-ops-tmp2:~# curl -X POST "http://api-in.stone.netease.com/kuafu/api/v3/form/submit?gwClientId=724&gwClientUser=wb.zhangjian17&gwTimestamp=1743562308&gwSignature=e60a5263999917f1cc5fd4337bd2fe85" -H "Content-Type: application/json" -d '{ "processDefId": "申请夸父OpenApi权限:6:150135612", "variables": { "是否需要业务处理恢复": "是", "是否需要发送通知": "是", "priority": "普通", "故障描述": "music-hadoop-720.gy.ntes", "产品名称": "\"value\":\"猛犸大数据平台\",\"label\":\"猛犸大数据平台\",\"key\":\"猛犸大数据平台\"", "故障部件": "\"硬盘\",\"其他\"", "影响": "理论无影响", "topic": "服务器维修-猛犸大数据平台-music-hadoop-720.gy.ntes-硬盘-其他", "预维修时间": "2025-04-02 11:26:02" "主机名": "music-hadoop-720.gy.ntes" "跟踪者": "ZQ05523" "工单优先级": "普通" }, "user": { "account":"wb.zhangjian17", "jobNumber":"ZQ05523", "mail":"wb.zhangjian17@corp.netease.com", "name":"张建" } }' {"message":"{\"timestamp\":1743565801215,\"status\":400,\"error\":\"Bad Request\",\"exception\":\"org.springframework.http.converter.HttpMessageNotReadableException\",\"message\":\"JSON parse error: Unexpected character ('\\\"' (code 34)): was expecting comma to separate Object entries\\n at [Source: java.io.PushbackInputStream@4af69e81; line: 13, column: 10]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('\\\"' (code 34)): was expecting comma to separate Object entries\\n at [Source: java.io.PushbackInputStream@4af69e81; line: 13, column: 10]\\n at [Source: java.io.PushbackInputStream@4af69e81; line: 12, column: 28] (through reference chain: com.netease.opstask.dao.dt.SubmitVariable[\\\"variables\\\"])\",\"path\":\"/api/3.0/form/submit\"}","code":500} root@yunxin-ops-tmp2:~#
04-03
root@yunxin-ops-tmp2:~# curl -X POST "http://api-in.stone.netease.com/kuafu/api/v3/form/submit?gwClientId=724&gwClientUser=wb.zhangjian17&gwTimestamp=1743577802&gwSignature=9b8826b0e17e6d5f7006df00b43665db" -H "Content-Type: application/json" -d '{ "processDefId": "服务器维修:40:229789844", "variables": { "是否需要业务处理恢复": "是", "是否需要发送通知": "是", "priority": "普通", "故障描述": "music-hadoop-720.gy.ntes", "产品名称": { "value": "猛犸大数据平台", "label": "猛犸大数据平台", "key": "猛犸大数据平台" }, "故障部件": ["硬盘", "其他"], "影响": "理论无影响", "主题": "服务器维修-猛犸大数据平台-music-hadoop-720.gy.ntes-硬盘-其他", "预维修时间": "2025-04-02 11:26:02", "自动化处理附件": "", "主机名": "music-hadoop-720.gy.ntes", "跟踪者": "ZQ05523", } "user": { "account": "wb.zhangjian17", "jobNumber": "ZQ05523", "mail": "wb.zhangjian17@corp.netease.com", "name": "张建" }' {"message":"{\"timestamp\":1743583135680,\"status\":400,\"error\":\"Bad Request\",\"exception\":\"org.springframework.http.converter.HttpMessageNotReadableException\",\"message\":\"JSON parse error: Unexpected character ('}' (code 125)): was expecting double-quote to start field name\\n at [Source: java.io.PushbackInputStream@5c8f8e36; line: 20, column: 5]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name\\n at [Source: java.io.PushbackInputStream@5c8f8e36; line: 20, column: 5]\\n at [Source: java.io.PushbackInputStream@5c8f8e36; line: 19, column: 17] (through reference chain: com.netease.opstask.dao.dt.SubmitVariable[\\\"variables\\\"])\",\"path\":\"/api/3.0/form/submit\"}","code":500} root@yunxin-ops-tmp2:~#
04-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值