“给你第二次机会”——小议PushbackInputStream

stream

jungleford如是说
    PushbackInputStream和PushbackReader是Java I/O系统里两个比较让人迷惑的类,我以前对它(们)就不太了解,直到某一天看了以前水母Java版的牛人zms的评论和一些资料以后才有所获益。这是几个月以前的事情了,这几天写有关序列化的总结时才想到这也不失为一个好的话题。

一个允许你反悔的hook

    Java I/O系统是一个典型的Decorator模式的实现,它以InputStream/OutputStream为基本核心,通过继承关系,不断为该核心添加新的功能,如文件流、缓冲、加解密等。对I/O系统设计模式感兴趣的话,可以参考developerWorks上的一篇文章:从Java类库看设计模式。Java I/O默认是不缓冲流的,所谓“缓冲”就是先把从流中得到的一块字节序列暂存在一个被称为buffer的内部字节数组里,然后你可以一下子取到这一整块的字节数据,没有缓冲的流只能一个字节一个字节读,效率孰高孰低一目了然。有两个特殊的输入流实现了缓冲功能,一个是我们常用的BufferedInputStream,像读文件我们常用
BufferedInputStream in = new BufferedInputStream(new FileInputStream("datafile"));while ((b = in.read()) != -1){  ...}in.close(); 
    这是我们几乎不用查什么JDK文档就能信手拈来的代码段,写的时候也应该思考一下套一个BufferedInputStream的意义何在。另一个就是我们不怎么看到的PushbackInputStream(其对应的字符流模式为PushbackReader)。    在通常状态下,“流”意味着“一次性”,就是说你进行了一次操作后它的状态就变了,譬如读,无论是文件还是socket,你读的过程中一个潜在的“读指针”一样的东东就在移动,你无法在读以后再重新定位(当然RandomAccessFile是另一种情况),如果你以前奇怪为什么数据库操作中ResultSet里get某个字段以后就不能再第二次get它了,这里或许是个解释。但好在PushbackInputStream给了我们第二次读的机会。我们先来区别一下“监听”和“截获”的概念,“监听”就是把得到的消息copy一份,原始消息并不作任何改变地传递到目的地;而“截获”则是先把消息“扣押”下来,不让其自动转给目标,而是先进行一些处理以后在转发给目标(如果是网络安全专业的背景知识,大概知道“监听”是对“机密性”的攻击,而“截获”不仅是对“机密性”还是对“完整性”的攻击)。有的朋友大概对hook这个名词有些了解,它是一种Windows的一种消息处理机制,似乎就是一种消息截获手段,但我对Windows编程一窍不通//shy;此外,如果你熟悉Servlet的话,也能找到像Filter这样的处理机制,在对每个HTTP请求/应答进行转发之前,先在里头耍一点花招,确定哪些予以转发,哪些屏蔽掉,这也算是“截获”吧。通过上面的介绍,我们不妨把PushbackInputStream看成是对输入流的一种“截获”手段,其中最重要的方法是unread:
public void unread(int b) throws IOExceptionpublic void unread(byte[] b) throws IOExceptionpublic void unread(byte[] b, int off, int len) throws IOException
    我们可以想象一下,PushbackInputStream内置一个缓冲区(事实上,你可以从它的源代码里找到这个protected的字节数组),当低层流进来时先流进这个buffer,在你把流“物归原主”之前还有机会对它耍花招,然后再用unread方法“反悔”一下,把缓冲区里已经读过的内容(一般是没有被改动的,当然你也可以改动它,那就失去“归赵”的意义了,因为已经不是“完璧”了)再插入到流的头部,下次读的时候是流剩余的部分再加上从缓冲区“归还”的部分。上面三个unread方法分别代表从缓冲区“归还”一个字节、一个字节数组以及一个字节数组中指定的部分。    PushbackInputStream是对二进制流的处理,字符流下相对应的就是PushbackReader。

有什么用?

    学过编译的话就容易理解了,比如从左向右扫描字符流“for(int i=0;i<10;i++)”,扫描到“for”是不是就可以说是个关键字了呢?不行,说不定后面是“for1”,那就是个变量而不是关键字了,知道看到“(”才恍然大悟,哦,我可以安全地说“看到for关键字”了,但“(”还得归还给输入流,因为需要后面继续扫描。在上下文相关语言里,就更需要这种补偿机制。又如,在解析HTML文档的时候,我需要根据它的“meta”标签的“charset”属性来决定使用哪种字符集进行解析,但HTML可不是“charset”而是“<html>”开头的哦!所以需要通过PushbackInputStream缓冲前面一段内容,等取到字符集名称后在把读到的流全部归还,再用指定的字符集进行解析。

参考资料
Java Network Programming. by Elliotte R. Harold zms兄在水母的帖子. by zms(无奈的是,水木清华已经不能对校外开放了) JDK 1.4.2 Documentation. by java.sun.com

时间: 2024-09-20 07:47:41

“给你第二次机会”——小议PushbackInputStream的相关文章

乔布斯辞职:苹果的第二次机会

"你那么爱他,为什么不将他留下."因为没有人可以长生不老.不病不休,苹果不得不在无奈之中完成了一次帮带传递. 就像一支保持连胜的足球队通常不会轻易改变首发阵容一样,一家正在成功的企业突然宣布更换舵手,肯定是一项艰难的决定.尤其是对于苹果而言.因为上个世纪80年代末至90年代,乔布斯离去不久,苹果便在短时间内盛极而衰,濒临破产,当年的梦魇还仍未散去,而这一次,乔布斯又要离开了. 不过这确实又是苹果的一次机会,一次从成功跨越到伟大的机会."企业就是企业家的背影",尤其是

被错过的最佳并购机会

浙商已经错过了两波历史性并购机遇.但接下来的5年后,还有第三次并购的机会,那就是国有股减持.在三次并购机会来临后,所有的行业大格局将基本定型. --<2008中国最具并购价值50家上市公司榜单>回顾 本刊记者 楼方芳 "眼看着经济的回暖,上证指数去年到今年这一年间翻了一倍. 回想去年年底没有出手并购上市公司,真有些惋惜和后悔!" 说这话的是余姚立兴电塑件有限公司董事长郑建立. 去年11月,他参加了由<浙商>杂志主办的"2008中国上市公司并购重组高峰论

未来五年物联网带来庞大创业机会

日前,马云在杭州云栖大会上演讲时表示,人类的第一次50年的技术革命,是对体能的释放,第二次50年的技术革命是对能源的利用,而这一次技术革命也会是50年.前20年是互联网技术的大发展,未来30年是互联网融入社会的时代,这30年才是真正创业巨大的机会.这个时代核心的能源是数据,计算能力将成为生产力. 未来中国有四大创业机会 第一.人口红利 中国人多,所以中国的第一大机会是,围绕着13亿人口出现的金融.旅游.教育.医疗.物流.生活服务.招聘等等,这些统统都变成了一个巨大的生意.中国十三亿人中有五六亿的

盛大千金买马骨谋略抓住站在巨人肩膀上机会

利润动辄高达百分之八九十的网游行业,总能给从业者深度创业"诱惑".然而,面对已经成功上市的10家网游企业,如何能在这些"大象"的影子下发展壮大,成为后进研发团队面临的难题. 在行业头把交椅坐了十多年的盛大抛出了橄榄枝,在其平台化战略之下,"千金买马骨",为有创意的产品和团队打开大门,甚至对于盛大内部想要创业的员工都给予了最大限度的支持. 在这样开放的心态之下,中小研发团队有了实现梦想的机会,而盛大也可以充分补充新鲜血液,实现产品线的多元化发展.

半年销量全球第一汽车股关注三类投资机会

每经记者 朱秀伟 在汽车销量连续"井喷"后,原本属淡季6月又再度超出市场预期.业内人士认为,除销量继续增长外,"利润"的增长更让人欣喜,"量长利增"的局面在下半年有望延续,而目前汽车股估值已不便宜,建议投资者关注三类投资机会. 6月汽车销量再度井喷 本周四,中国汽车工业协会发布的6月汽车产销数据显示,6月汽车产销分别完成115.32万辆和114.21万辆,产销量仅次于创历史新高的4月,用"形势喜人"来形容整个上半年汽车形势再恰

福布斯:AOL新任CEO获得二次证明机会

导读:美国<福布斯>杂志网络版今天发表分析文章称,作为分拆AOL的舵手,谷歌老兵.AOL新任CEO蒂姆·阿姆斯特朗(Tim Armstrong)将获得一个证明自己的机会,即证明将赌注押在这个已经"萎缩"的网联网巨头身上的做法是正确而明智的. 时代华纳当初与AOL合并所能让人感知到的协同效益一度具有极高的欺骗性和诱惑力,就连谷歌负责广告业务的高管阿姆斯特朗也希望参与其中.合并后不久,阿姆斯特朗便签署一项协议.有报道说,在合并过程中,谷歌曾出资10亿美元购买AOL 5%的股份.

中年创业族该如何做才能掌握机会

别以为自己当老板很容易!有人创业第一年找不到半个客户,一百万一下子就花光.有人自行创业后,没有大公司的蔽荫,"感觉自己好像流浪狗".中年创业族该如何做,才能掌握机会,减少创业的风险? 光看表面,自由工作者.小型创业者好像很自由.高兴时,可以睡到自然醒,不想工作时,可以一大早就冲到海边.山上休闲赏美景.不用每天按时上下班.不用每天面对同一个老板.这种弹性.自由与自主的人生,几乎是每个上班族所羡慕的境界. 但是,在这些看似自由的背后,个人创业者其实常要历经一段艰辛,才能走出一条自己的路.

缓存淘汰算法系列之3——FIFO类

缓存淘汰算法系列之3--FIFO类 1 FIFO 1.1. 原理 按照"先进先出(First In,First Out)"的原理淘汰数据. 1.2. 实现 FIFO队列,具体实现如下: 1. 新访问的数据插入FIFO队列尾部,数据在FIFO队列中顺序移动: 2. 淘汰FIFO队列头部的数据: 1.3. 分析 l 命中率 命中率很低,因为命中率太低,实际应用中基本上不会采用. l 复杂度 简单 l 代价 实现代价很小. 2. Second Chance 2.1. 原理 FIFO算法的改进

站在每个用户角度看百度

近来百度"竟价门"事件已成为当今互联网热门话题,更是国人关注的话题!这段时间我也非常关注百度"竟价门"事件的动态,以下为纯个人看法!­ 普通网民 对于普通网民来说,有大部分人依然是支持百度的,从这里可以看得出百度在网民心目中的地位已经是深入民心了.其实对于普通网民的想法是非常简单的,也就是说百度能帮助他们搜索出他们想要的东西,他们并不会去考虑体验上的问题.很多用户从来不会去考虑自己所用的搜索引擎会给自己带来时间上的浪费,因为这部分网民已经习惯了在百度上花时间找东西.