我學(xué) Java IO

說起來,我接觸 Java 是從大一下學(xué)期開始的,通過逐步學(xué)習(xí)接觸到了 Java IO 這個很重要的模塊,同時也是讓我很頭疼的一個模塊,好像一直都沒怎么學(xué)會。在我的腦子里,一直都是那種,這么多相關(guān)的類,怎么能記住啊。再加上,后來轉(zhuǎn)戰(zhàn) Android 就更少有直接使用 Java IO 去操作文件的機會。一個偶然的機會,我學(xué)到了可以從另一種視角看 Java IO,突然覺得,Java IO,并不難。現(xiàn)在,我來記錄并分享一點自己的經(jīng)驗。

如果是講操作文件的 API 的話,那估計得寫的老長,事實上,我對 Java IO 相關(guān)的 API 并不太熟,而且我也不打算講。在這里我可能是從另一種我覺得是站在全局的角度去看 Java IO。

通常的,我們使用 Java IO 都是為了去對文件進(jìn)行操作,或讀或?qū)憽Wx:從磁盤、網(wǎng)絡(luò)等渠道將文件內(nèi)容讀入到內(nèi)存中;寫:通過將內(nèi)存中的數(shù)據(jù)寫入到磁盤、網(wǎng)絡(luò)等進(jìn)行持久化保存。

Java Io

以前啊,我就光想著 Java IO 就是這么讀文件,寫文件,也沒什么的嘛。不就是對文件的操作嘛,沒什么可講的的,現(xiàn)在我不這么想了。現(xiàn)在怎么想呢?我換了一種思路。

我們使用 Java IO 寫東西,寫的是什么?是字符串,字符串是什么?是字符數(shù)組組成的一種的對象,什么是字符?字符就是可以通過字節(jié)碼的形式表現(xiàn)出來一種東西。而字節(jié)碼就是 OutputStream 以及 InputStream 直接能進(jìn)行操作的東西,那什么是它們不是直接操作的?不就是字符串、字符數(shù)組嘛。可是我們在寫程序的時候,誰還記得這個字符串的字節(jié)碼是什么,那個字符的字節(jié)碼是啥。我們都是直接操作字符串以及少部分情況操作字符數(shù)組的。那怎么辦?

String To byte

有的人說,通過各種轉(zhuǎn)換就可以對應(yīng)的字節(jié)碼,然后進(jìn)行操作。事實上就是這樣的,Java 提供給我們的方法也是如此,通過各種轉(zhuǎn)換得到可以操作 String 或是字符數(shù)組,然后進(jìn)行操作。比如,OutputStreamWriter 就可以使用 OutputStreamWriter.write(String); 來直接操作字符串進(jìn)行寫入文件,還有通過 BufferedReader 就可以使用 String lineString = bufferedReader.readLine() 來直接進(jìn)行讀取一行文字。可是總一些我們可以從另一種角度看的東西。

仔細(xì)看一下,第二幅圖,沒什么啊,不就是數(shù)據(jù)在他們之間進(jìn)行轉(zhuǎn)換嗎,有什么的?是這樣的,但是還可以有另一種看法,字符串就是另種形式的字符數(shù)組,而字節(jié)數(shù)組就是另一種形式的字符數(shù)組。他們還是自己本身,只不過穿上了一件 “衣服” 而已。穿上了這身衣服,你以為他變了,從字符串 String 變成了字符數(shù)組 char[] 實際上,他還是 String ,只是不同的表現(xiàn)形態(tài)而已。沒有什么不同,他還是他,只是你需要看穿這件 “衣服”。

那你說,既然數(shù)據(jù)本身都沒有變化,只是穿了件衣服,那為什么 Java IO 的操作,顯得那么的麻煩?因為,為了方便處理,也給處理過程穿上了衣服。OutputStream 只能處理字節(jié)數(shù)組,而包裹了一層 OutputStream 的 OutputStreamWriter 就能直接的操作 char[] 和 String。

好麻煩啊,就不能有一個直接能用來操作字符串的對象嗎,每回寫文件讀寫的時候,都得寫好幾個對象,煩死了。別煩啊,這樣做是有這樣做的理由的。就拿讀操作(InputStream)來說吧,我曾天真的以為讀操作只有一個來源就是,文件(FileInputStream)。后來才發(fā)現(xiàn),竟然有 ByteArrayInputStreamObjectInputStreamPipedInputStreamStringBufferInputStream 等等(只列出部分,全部的都 在這 呢。他們分別處理字節(jié)數(shù)組、被序列化的對象、線程間的輸入流以及來自 StringBuffer 的輸入。對應(yīng)的還有寫操作(OutputStream)整體來說,雖然比 InputStream 少,但是也有好幾個呢,ByteArrayOutputStreamFileOutputStreamFilterOutputStreamObjectOutputStreamPipedOutputStream

如果這么多種輸入或是輸出方式,都要能處理 String、long、int 這種,或是再兼容一些其他方便我們程序員操作的方法,那類就太多了,想想一下,一個 FileInputStream 就可能變成了 StringFileInputStream、LongFileInputStream、IntegerFileInputStream ,想想就覺得可怕。所以,Java 采用了穿 “衣服” 的形式,讓程序員通過對數(shù)據(jù)穿上不同的衣服,從而達(dá)到操作不同數(shù)據(jù)類型的效果。

image

FileInputStream 只能讀出字節(jié)數(shù)組,InputStreamReader 可以讀出字符數(shù)組,通過不同的對象進(jìn)行轉(zhuǎn)換,就能讀出或是寫出不同形式的數(shù)據(jù)。而且 FileInputStream 可以作為 InputStreamReader 的提供者,這樣的話,就能應(yīng)對足夠復(fù)雜的場景,只要給當(dāng)前的對象穿上另一件"衣服"就能搖身一變成為你想要的結(jié)果。

感覺很神奇啊,只要是 InputStream 相關(guān)的類,都可以作為生成下一個 xxInputStream 對象輸入,只要是一個 OutputStream 相關(guān)的類都可以作為生成下一個 xxOutputStream 對象的輸入。其實啊,知道細(xì)節(jié)之后就不會覺得神奇了,只會覺得設(shè)計的很巧妙。

FilterOutputStreamFilterInputStream 這兩個是關(guān)鍵,他們倆分別繼承自 OutputStream 和 InputStream,同時又有非常多的子類,就是通過這些子類來實現(xiàn)各種轉(zhuǎn)換,什么線程的輸入做到輸出字符數(shù)組、被序列化的對象輸出字符串等等。

FilterOutputStream 子類:

  • BufferedOutputStream
  • CheckedOutputStream
  • CipherOutputStream
  • DataOutputStream
  • DeflaterOutputStream
  • DigestOutputStream
  • InflaterOutputStream
  • PrintStream

FilterInputStream 子類:

  • BufferedInputStream
  • CheckedInputStream
  • CipherInputStream
  • DataInputStream
  • DeflaterInputStream
  • DigestInputStream
  • InflaterInputStream
  • LineNumberInputStream
  • ProgressMonitorInputStream
  • PushbackInputStream

這些子類固然是很重要的,便于操作不同的數(shù)據(jù)類型,同樣重要的還有 Reader、Writer。這兩個類并不繼承 InputStream 與 OutputStream 但通過他們的子類,也同樣能實現(xiàn)更簡單的文件讀寫。比如 OutputStreamWriter、InputStreamReader。都可以直接對 String 進(jìn)行操作。再搭配上 InputStream 和 OutputStream 那一大家子,真的是可以對文件可以為所欲為了。

對了,還一個 Buffer,它直譯過來是緩沖的意思,干什么用的呢?是這樣的,磁盤的讀取或?qū)懭氲乃俣炔]有像直接操作內(nèi)存那樣快,所以需要一個緩沖的東西用來緩解雙方操作上的時間差,比如在寫的時候,可以先寫到緩沖區(qū),然后再把緩沖區(qū)的數(shù)據(jù)一點點寫到磁盤上。或者說,從磁盤讀數(shù)據(jù)的時候,先讀一些,讀到緩沖區(qū),等讀的東西,夠多了,然后再一起寫入到內(nèi)存中去。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內(nèi)容