天天看點

java的拉結歸宗_【Java】基礎43:萬流歸宗

今天是我自學Java的第43天。

感謝你的觀看,謝謝你。

話不多說,開始今天的學習:

java的拉結歸宗_【Java】基礎43:萬流歸宗

前兩天學習了兩種非常基礎的IO流:位元組流和字元流。

今天我們要繼續學習一些更強大的流:

比如能夠高效讀寫的緩沖流;能夠轉換編碼的轉換流;能夠持久化存儲對象的序列化流……等等。

不要一看流那麼多,感覺很難記,其實真心不難,無論多少流,核心都是兩類:

InputStream位元組輸入流,核心方法read(),讀硬碟資料輸入到記憶體,對應字元輸入流Reader;

OutputStream位元組輸出流,核心方法writer(),寫記憶體資料輸出到硬碟,對應字元輸出流Writer。

java的拉結歸宗_【Java】基礎43:萬流歸宗

所有的流都是以這兩種為核心,都是由位元組輸出流和位元組輸入流演化而來,正所謂萬流歸宗就是這個道理。使用方法都是大同小異的,隻不過字首不一樣。

一、緩沖流

Buffered,翻譯為緩沖的,是以緩沖流字首為Buffered。

它也叫高效流,顧名思義,其使用起來效率很高,經常會使用到它。

它為什麼更高效?

因為用空間換時間:底層有一個8K緩沖區專門來做這件事,進而縮短時間,更加地高效。

拿一個我們現實裡的例子:電腦卡頓,我們将記憶體增加,可以在一定程度上解決卡頓。

因為同樣是一個程式,以前記憶體小,隻能用100M記憶體處理這個程式;現在記憶體大了,專門用200M記憶體來處理,是以更快了。

這就是用空間換時間。

1.位元組緩沖流

java的拉結歸宗_【Java】基礎43:萬流歸宗

①構造方法

位元組緩沖流,它是在位元組流的基礎上建立的,是以其參數就是位元組流。

其中它還有一個構造方法,額外有一個參數size,可以設定緩沖區的大小,但一般很少使用,都會使用其預設的8K緩沖區。

②複制檔案

無論是什麼流,它複制檔案方法都是大同小異的,無外乎就是read方法,和writer方法,再加上while循環。

③關流

位元組緩沖流關閉了,其位元組流也會跟着關閉,是以上述雖然建立了4個流,但是隻用關閉緩沖流。

2.字元緩沖流

java的拉結歸宗_【Java】基礎43:萬流歸宗

①字元緩沖輸出流

和位元組緩沖流一樣,它也是在字元流的基礎上建立的,是以其構造方法參數就是字元流。

其中有一個特有的方法叫newline(),也就是換行;

和寫入換行符System.lineSepatator()作用一樣。

②字元緩沖輸入流

構造方法一樣,不做闡述。

其中有一個特有方法readLine(),作用是一次可以讀一行。

二、轉換流

昨天學習過編碼表,編碼表就可以了解成翻譯,可以将位元組翻譯成字元。

編碼表有很多種,就好比翻譯也會有中文翻譯,英文翻譯,日文翻譯一樣。

是以編碼表不一緻的話就會出現亂碼。

轉換流,便是位元組與字元之間的轉換的橋梁,它能夠指定編碼表,防止出現亂碼。

java的拉結歸宗_【Java】基礎43:萬流歸宗

①轉換輸入流

InputStreamReader,它是Reader的子類。

這個名稱就特有意思,InputStream位元組流,Reader字元流。

是以轉換流本質上就是從位元組流而來的字元流,在其構造方法中可以指定編碼表。

②轉換輸出流

OutputStreamReader,和輸入流是一樣的,大同小異。

轉換流一般什麼時候使用呢?

比如說,我本來一直都是用UTF-8編碼表,這有一個特殊需求,有一個特殊檔案就是要用GBK編碼表。

這種時候就可以用到轉換流,但使用不常見。

三、序列化流和反序列化流

前面學了這麼多的流,本質上都在操作位元組,字元。

現有一個問題:如何将一個自定義對象(比如說學生對象)存儲到檔案中, 并讀取出來?

序列化流就是用來解決這個問題的,序列化 :将資料結構或對象轉換成二進制串的過程,也就是寫入檔案(輸出流)。

反序列化 :二進制串轉換成資料結構或對象的過程,也就是讀取檔案(輸入流)。

序列化流和反序列化流的字首為Object,Object代表着所有對象。

1.使用前提

java的拉結歸宗_【Java】基礎43:萬流歸宗

①實作Serializable接口

Serializable,序列化的意思,它是Java裡的一個接口。

若想要将自定義對象存儲到檔案中,該對象對應的類必須要實作該接口。

②transient關鍵字

transient,瞬态的意思。

該類的所有屬性必須是可序列化的,如果有一個屬性不需要可序列化的,則該屬性必須使用transient 關鍵字修飾,注明是瞬态的。

③序列版本号

Serializable接口給序列化的類,提供了一個序列版本号,目的在于驗證序列化的對象和對應類是否版本比對。

也就是說,哪怕類中的屬性發生了變化,在讀取檔案時(反序列化),也能根據序列版本号找到對應的對象。

2.序列化流

ObjectOutputStream類,這是一個輸出流。

序列化流,将Java對象寫出到檔案,實作對象的持久存儲。

java的拉結歸宗_【Java】基礎43:萬流歸宗

①建立序列化流

建立一個對象,以及一個檔案obj.txt。

同時建立一個序列化流。

②寫入對象

writeObject()方法,将某個對象寫入到obj.txt檔案中。

3.反序列化流

ObjectInputStream類,這是一個輸入流。

反序列化流,将之前使用ObjectOutputStream序列化的原始資料恢複為對象。

java的拉結歸宗_【Java】基礎43:萬流歸宗

①建立反序列化流

②讀取對象

readObject()方法,讀取對象,該對象也就是序列化存入的對象。

最後在提一個流:列印流

PrintStream:

java的拉結歸宗_【Java】基礎43:萬流歸宗

①這是最常見的系統列印方式,會在控制台上輸出。

②建立列印流

列印流的底層也就是建立了一個FileOutputStream(位元組輸出流),詳情見④,是以位元組輸出流有的方法它也有。

其中也有println方法,也能輸入資料到對應檔案裡面。

③改變系統列印資料的流向

這個是什麼意思呢?

就是說,調用setOut(ps)後,系統列印資料不會在控制台上輸出了,而是會列印到列印流ps對應的那個檔案裡。

總結:

java的拉結歸宗_【Java】基礎43:萬流歸宗