<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jungleford's Home BlogJava分舵

    Java技術研究,兼探討歷史話題

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      24 Posts :: 0 Stories :: 53 Comments :: 0 Trackbacks
    jungleford如是說

        PushbackInputStreamPushbackReaderJava 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編程幾乎一竅不通;此外,如果你熟悉Servlet的話,也能找到像Filter這樣的處理機制,在對每個HTTP請求/應答進行轉發之前,先在里頭耍一點花招,確定哪些予以轉發,哪些屏蔽掉,這也算是“截獲”吧。通過上面的介紹,我們不妨把PushbackInputStream看成是對輸入流的一種“截獲”手段,其中最重要的方法是unread:

    public void unread(int b) throws IOException
    public void
    unread(byte[] b) throws IOException
    public 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緩沖前面一段內容,等取到字符集名稱后在把讀到的流全部歸還,再用指定的字符集進行解析。

    參考資料

    posted on 2005-04-02 22:03 jungleford 閱讀(700) 評論(0)  編輯  收藏 所屬分類: 咖啡屋 - Java 技術研究
    主站蜘蛛池模板: a毛片在线还看免费网站| h视频免费高清在线观看| 成年免费大片黄在线观看岛国| 亚洲AV无码久久寂寞少妇| 华人在线精品免费观看| 五月天网站亚洲小说| 无码人妻久久一区二区三区免费 | 国产精品亚洲专区无码唯爱网| 毛片A级毛片免费播放| 亚洲精品无播放器在线播放| 国产男女猛烈无遮挡免费视频网站 | 大地资源免费更新在线播放| 亚洲色欲啪啪久久WWW综合网| 天天摸天天碰成人免费视频| 狠狠综合亚洲综合亚洲色| 亚洲AV日韩精品一区二区三区| 一级毛片正片免费视频手机看| 国产亚洲精品成人a v小说| 毛片免费在线观看| 亚洲一区二区三区免费观看| 国产无遮挡又黄又爽免费视频| 国产精品亚洲综合| 国产av无码专区亚洲av桃花庵| 久久久久久曰本AV免费免费| 亚洲欧好州第一的日产suv| 亚洲色偷偷综合亚洲AV伊人| 免费女人高潮流视频在线观看| 亚洲最大无码中文字幕| 亚洲国产日韩成人综合天堂 | A国产一区二区免费入口| 7777久久亚洲中文字幕蜜桃| 色吊丝最新永久免费观看网站| 人人公开免费超级碰碰碰视频| 亚洲第一视频网站| 韩国欧洲一级毛片免费| 日本在线免费观看| 亚洲国产无线乱码在线观看| 亚洲国产精品自在在线观看 | 亚洲人AV永久一区二区三区久久| 久久久久久久99精品免费观看| 亚洲资源最新版在线观看|