? 一直以來對IO這塊的東西認識都不是很清楚。每次涉及這塊的東西,一般都找點現成的代碼復制粘貼一下。這可不好,于是靜下心來好好弄一下。
?
?
什么是IO?
???
一提起IO給人的感覺就比較復雜(不過確實也挺復雜的),可能是學C的時候嚇怕了,呵呵。不過,理一下思路還是比較清晰的。在Java里,IO說白了就是對讀、寫的一種抽象。沒有什么其他的復雜的東西。至于讀什么、寫什么,那就看你想讀什么、想寫什么,由自己控制了。
?
?
讀什么?寫什么?
看看下面這個圖會清楚很多(只用看InputStream就行,OutputStream一樣):
?
?
?
????
大家可以看一下直接繼承InputStream的幾個類ByteArrayInputStream、FileInputStream、StringBufferInputStream(PipedInputSteram和SequenceInputStream一般不用)。呵呵,看看這幾個類的構造函數就明了了。第一個是把byte數字作為IO源讀取byte數組里的東西,第二個是把文件作為IO源讀取文件里的東西,第三個是把String作為IO源讀取String里面的東西。這么看這幾個IO實在簡單。說白了就是從byte數組、文件、String按字節讀取罷了.....
??? 一句簡單的話說:IO體系第一級繼承的幾個類解決了從哪兒讀或者寫到哪兒的問題。
?
?
怎么讀?怎么寫?
???
試想一下,現在要讀一個幾百兆的文件,怎么讀呢?是一下子把整個文件都讀到內存慢慢分析呢,還是每次讀只讀一個字節逐個分析呢?顯然兩個都不好,于是我們想到了緩沖。所以IO體系上有了BufferedInputStream。再想一下,現在你想寫一個“3.1415926”到文件里怎么寫?總不能自己把這個數的二進制形式寫出來,轉成byte數組寫到文件里吧。即便寫進去了讀的時候怎么讀啊?誰知道你寫進去的是數字而不是其他字符呢?
??? 于是針對怎么讀Java
IO體系上出現了一個分支FilerInoutStream(FilterOutputStream)。繼承了這個類的幾個類各自對怎么讀、寫提供了不同的支持。Buffered提供了緩沖,LineNumber提供了對不同類型數據的讀寫。
??? 還是一句話:IO體系的第二級繼承解決了怎么讀、怎么寫。
?
?
以不變應萬變
???
說IO不能不說他的Decorator(裝飾)模式。此模式在這里的應用確實很經典!從上面兩段的分析看來Java的IO就是分成兩部分從哪兒讀(寫)和怎么讀(寫)。想想看,一個數據源可能需要不同的讀寫方式、而不同的數據源都可能需要同一直讀寫方式。于是這里的組合方式是一種乘積。n個數據源×n中處理方式×(n-1)處理方式(有時候可能涉及多種處理方式的疊加)=n^3。想想看,要是一個一個寫還不寫死......
???
從IO體系的根看,InputStream(OutputStream)提供了最根本的read(write)方法。各子類提供各自實現。而得益于Decorator,各子類還可以把自己的處理方式加到read(write)的前后,形成一種處理方式的疊加。
??? JDK這部分的代碼比較簡單。看一下就大概知道Decorator怎么實現的了。
?
?
追根溯源
????
我們見到的IO最大的應用一個應該是數據的持久化,FileinputStream(FileOutputStream)已經實現了。而另一個則是網絡傳輸。之前我就很想知道IO是怎么在網絡上實現傳輸的?還有上面說的幾個IO都不存在“阻塞”問題,那么IO的阻塞實在哪兒產生的呢?
???? 找了半天對于找到了下面一句:
???? class SocketInputStream extends FileInputStream
????
再追下去就找到了一些native方法,這個就超出我能力之外了。不過可以猜想,底層的東西應該就是C的一些文件讀寫了。這個就不是Java的問題:)目前暫時這么認為,以后或許能發現一些新的東西。
?
?
根深蒂固的痛——國際化
????
編碼問題不僅是Java頭痛的問題,也是每一個用Java的人都頭痛的問題。IO也不例外。InputStream(OutputStream)體系都是針對字節(byte)進行讀寫的。這樣的問題是字節可能是沒有意義的,只有幾個字節聯合轉換才能得到有意義的東西。所以如果是字節還要再次進行編解碼才能得到我們想要的東西。
???
為了避免這個麻煩,字符體系(Read、Write)產生了。他們可以對流進行編解碼,這樣可以直接得到用戶想要的東西。兩個體系大大體上都是對應的。再多的東西我也沒有深入了解了:)
??? 還有一個要提的是,什么時候用字符、什么時候用字節呢?TIJ里有交代:大部分時候用字符,字符不行的時候再考慮字節。呵呵,挺簡練的。
?
?
日新月異
???
nio應該是老掉牙的東西了。不過對于我這個初始IO的人來說還有待進一步了解。目前知道兩點:上面的IO體系的底層都已經用nio重寫了,所以速度上應該差不多。這樣看來,一般情況下用上面的IO是沒問題的。再一個是,nio最大的優勢在于他的“非阻塞IO”,不過這個東東是用在網絡編程的。一般也用不上。
??? 再新的東西就是前兩天看到的一個blog,關于aio(異步IO)的大家有興趣可以自己看看。
posted on 2006-11-25 21:26
KeepRunning 閱讀(364)
評論(0) 編輯 收藏 所屬分類:
Java點滴