<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在线视频免费观看| 成年大片免费视频| 337p日本欧洲亚洲大胆裸体艺术| 久久伊人久久亚洲综合| www.亚洲日本| 99热在线精品免费播放6| 永久免费av无码网站大全| 亚洲人成中文字幕在线观看| 亚洲影视自拍揄拍愉拍| ssswww日本免费网站片| 波多野结衣免费在线| 亚洲精品无码乱码成人| 中中文字幕亚洲无线码| 黄色网址在线免费| 亚洲国产午夜中文字幕精品黄网站| 4444亚洲国产成人精品| 日韩在线视频免费| 成年女人毛片免费播放人| 亚洲av无码一区二区三区不卡 | 玖玖在线免费视频| 在线不卡免费视频| 久久亚洲中文字幕精品有坂深雪| 尤物视频在线免费观看| 在线免费视频一区二区| 亚洲视频一区二区在线观看| 国产一区视频在线免费观看| 亚洲精品熟女国产| 国产国产人免费视频成69大陆| 一个人免费观看www视频| 日本亚洲成高清一区二区三区| 国产亚洲男人的天堂在线观看| 18禁免费无码无遮挡不卡网站| 免费观看国产小粉嫩喷水| 亚洲a级在线观看| 最近中文字幕免费mv视频7| 亚洲色成人网一二三区| 日本特黄a级高清免费大片| 永久免费的网站在线观看| 少妇高潮太爽了在线观看免费|