學習Java之IO流的基礎概念詳解
一. IO流概念
首先給大家來解釋一下 “IO流” 這個概念,如果我們連 IO流 是個啥都不知道,也就沒必要繼續(xù)往下看了。在這里會從兩部分展開介紹IO流,即 “IO” 與 “流” 。
1. IO
IO其實代表的是兩個內(nèi)容,即 “I” 與 “O”,它們分別是 “In” 與 “Out” 的縮寫。
In:輸入, 代表著能夠接收數(shù)據(jù)的數(shù)據(jù)源對象,從外部設備把數(shù)據(jù)輸入到內(nèi)存;
Out:輸出, 代表著能夠產(chǎn)出數(shù)據(jù)的數(shù)據(jù)源對象,從內(nèi)存中輸出數(shù)據(jù)到外部設備。
對我們來說,大家只需要記住,輸入與輸出都是以內(nèi)存為參照物的即可!
2. 流
接下來咱們再來看看什么是 “流”!請先在腦海里想一下,“流”是一種什么樣的形態(tài)?其實Java中各個API的命名都是很形象的,絕對都做到了見名知意,這里的“流”就是一個很形象的概念!可以說,流是一組有序的數(shù)據(jù)序列,能把數(shù)據(jù)從一個地方帶到另一個地方。根據(jù)數(shù)據(jù)流向的不同,可以分為輸入(Input)流和輸出(Output)流兩種。
- 輸入流:當我們的代碼程序需要 讀入數(shù)據(jù) 的時候,可以開啟一個連通 數(shù)據(jù)源 ****的流(輸入流) ,這個數(shù)據(jù)源可以是文件、內(nèi)存、數(shù)據(jù)庫,或是網(wǎng)絡連接。
- 輸出流:同樣的,當我們的代碼程序需要 輸出數(shù)據(jù) 的時候,也可以開啟一個連通 目的地 ****的流(輸出流), 這個目的地一般是指我們的代碼程序。
你可以想象一下,我們的數(shù)據(jù)好像就是在數(shù)據(jù)源與目的地之間 “流動” 了起來。其實 流(stream)這個概念,一開始源于UNIX中的管道(pipe)概念 。 在UNIX中,管道是一條不間斷的字節(jié)流,用來實現(xiàn)程序或進程間的通信,或讀寫外圍設備、外部文件等。最后再給各位提取一下流的概念:
流是一組有順序的,有起點和終點的字節(jié)集合,是對數(shù)據(jù)傳輸?shù)目偡Q或抽象。數(shù)據(jù)在兩設備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸,根據(jù)數(shù)據(jù)傳輸?shù)奶匦钥梢詫⒘鞒橄鬄楦鞣N類,方便更直觀的進行數(shù)據(jù)操作。
3. IO流
最后,我們再把IO流的概念梳理一下。
程序中的數(shù)據(jù)需要移動傳輸,比如硬盤上的數(shù)據(jù)需要出現(xiàn)在顯示器上,從鍵盤輸入的內(nèi)容需要存儲在硬盤上,所有的這些操作都要進行數(shù)據(jù)傳輸,而在Java中負責進行數(shù)據(jù)傳輸?shù)募夹g就是“IO流”。這是一種按順序讀寫數(shù)據(jù)的模式,它的特點是單向流動,數(shù)據(jù)會像自來水一樣在水管中流動,所以我們把它稱為IO流。
外部的數(shù)據(jù)輸入到計算機,計算機內(nèi)部的數(shù)據(jù)輸出到外部,這個實現(xiàn)的過程就是由IO流來完成的,且輸入和輸出都是以內(nèi)存為中心的。
- Input輸入:是把數(shù)據(jù)從各種外部的輸入設備(鍵盤、麥克風等)中讀入到內(nèi)存,例如,把文件從硬盤讀取到內(nèi)存,從網(wǎng)絡讀取數(shù)據(jù)到內(nèi)存等;
- Output輸出:指把數(shù)據(jù)從內(nèi)存輸出到各種外部設備(如顯示器、磁盤等),例如,把數(shù)據(jù)從內(nèi)存寫入到文件,把數(shù)據(jù)從內(nèi)存輸出到網(wǎng)絡等。
我們之所以要以內(nèi)存為中心,是因為代碼要運行在內(nèi)存中,這就需要各種數(shù)據(jù)都必須進入到內(nèi)存中進行處理。大家要注意,IO流對數(shù)據(jù)的處理,只能按照數(shù)據(jù)序列的順序來進行,即前一個數(shù)據(jù)處理完之后才能處理后一個數(shù)據(jù),否則會產(chǎn)生異常。
二. 作用
那么根據(jù)上面對IO流的描述,我們就可以搞清楚出IO流的核心作用,如下:
IO流可以在數(shù)據(jù)源和目的地之間搭建一個傳輸通道,用于處理設備與代碼程序之間的數(shù)據(jù)傳輸,設備是指硬盤、內(nèi)存、數(shù)據(jù)庫、鍵盤錄入、網(wǎng)絡等。
一言以蔽之,IO流屏蔽了實際的設備處理數(shù)據(jù)細節(jié),我們不必關心其內(nèi)部具體的流動過程,只需知道IO流是用來處理設備之間數(shù)據(jù)傳輸?shù)募纯伞?/p>
三. 分類
如果你只看上面IO流的概念,感覺也沒有什么難度,但是關于IO流的學習,最難的是分類太多。IO流有著不同的劃分維度,如果我們根據(jù)這些不同的標準來分類的話,可以分類如下:
- 按IO流的流動方向分為: 輸入流和輸出流;
- 按IO流的數(shù)據(jù)單位分為: 字節(jié)流和字符流;
- 按IO流的不同功能分為: 節(jié)點流和處理流。
接下來會分別解釋一下這幾種類型。
1. 輸入流與輸出流
從IO流的流動方向上,我們知道IO流可以分為輸入流與輸出流,但不少初學者總是分不清輸入流與輸出流,甚至會把兩者搞反。所以接下來就再明確一下輸入流與輸出流的區(qū)別,我們來看下圖:
在上圖中,我們以家中自來水的進水與出水來形象的比喻輸入流與輸出流。
- 自來水公司相當于是數(shù)據(jù)源,我們家中的房子就相當于是目的地;
- 自來水公司的水進入到我們家里,這就是自來水的輸入;
- 我們家中產(chǎn)生的污水,要排到污水處理廠,這就是自來水的輸出。
在這個供水、排水的過程中,我們可以想一下,輸入、輸出是不是一個相對的概念呢?那么相對于哪個角色呢?沒錯!輸入、輸出都是相對于我們的房子來說的,進入到房子叫做輸入,從房子流出就叫做輸出。所以房子就是輸入和輸出的參照物,這就和內(nèi)存是IO流的輸入、輸出參照物一樣!
最后,再把上圖中的各角色明確一下:
- 數(shù)據(jù)源: 上圖中自來水公司的水池,用于提供自來水(數(shù)據(jù));
- 輸入流: 從自來水公司進到房子里的管道,攜帶著具體的數(shù)據(jù)家里來;
- 目的地: 上圖中的房子,這代表著我們項目的代碼程序,或者說是內(nèi)存;
- 輸出流: 從家中流出到污水廠的管道流,攜帶著具體的數(shù)據(jù)到污水廠;
- 數(shù)據(jù)目標: 最后的污水廠,這是用于持久化存儲污水(數(shù)據(jù))的地方,其實也是一種數(shù)據(jù)源。
所以,IO流中的輸入流與輸出流,入與出都是相對于內(nèi)存而言的。從某個數(shù)據(jù)源讀取數(shù)據(jù)到內(nèi)存中,被稱為輸入流;從內(nèi)存中把數(shù)據(jù)持久化保存到其他設備上,則被稱為輸出流。簡單一句話,流向內(nèi)存是輸入流,流出內(nèi)存的輸出流。 我們再來看下圖:
另外要注意,我們可以從輸入流中讀取信息,但不能對它寫;可以對輸出流進行寫操作,但不能對其讀。所以輸入也叫做讀取數(shù)據(jù),輸出也叫做作寫出數(shù)據(jù)!
2. 字節(jié)流與字符流
上面說了,按照數(shù)據(jù)流的數(shù)據(jù)單位不同,可以把IO流分為字節(jié)流與字符流,兩者的區(qū)別如下:
- 字節(jié)流: 字節(jié)流是以字節(jié)(8bit)為單位進行數(shù)據(jù)的按序傳輸,一次讀取或寫入一個字節(jié)(8位)的二進制數(shù)據(jù), 字節(jié)流能處理所有類型的數(shù)據(jù)(如圖片、音頻、視頻等) ;
- 字符流: 字符流以字符為單位進行數(shù)據(jù)的按序傳輸,根據(jù)碼表映射字符,一次讀取或寫入一個字符(可能是多個字節(jié)),一次讀入或寫出16位二進制數(shù)據(jù), 字符流只能處理文本文件中的字符類型數(shù)據(jù) 。
字節(jié)流和字符流的這些區(qū)別,主要是因為Java一個字節(jié)的空間是1個Byte,即8位;而一個字符的空間是2個Byte,即16位。另外Java的字節(jié)是有符號類型,字符是無符號類型!
另外我們還知道,計算機中的一切文件數(shù)據(jù)(文本、圖片、視頻等)在存儲時,都是以二進制的形式保存的,即都是一個一個的字節(jié),在傳輸時也同樣如此。所以,字節(jié)流可以傳輸任意類型的文件數(shù)據(jù)。在操作流的時候,我們要時刻明確,無論使用什么樣的流,底層傳輸?shù)氖冀K為二進制數(shù)據(jù)。
但如果我們需要讀寫的內(nèi)容是字符,并且字符不全是單字節(jié)表示的ASCII字符。有很多的字符是用Unicode編碼表示的,采用的是雙字節(jié),而InputerStream是用來處理單字節(jié)的,在處理字符文本時不是很方便,所以就需要有一種可以高效處理字符的流。字符流的本質(zhì)其實也是基于字節(jié)流的,所以字節(jié)流和字符流的原理其實也是相同的,只不過處理的數(shù)據(jù)單位大小不同而已。一般情況下,Java所有關于IO流的API,后綴是Stream的是字節(jié)流,后綴是Reader和Writer的是字符流。但你可能會問,我們在開發(fā)時,到底是要選擇字節(jié)流還是字符流呢?
答案就是,對于字節(jié)流和字符流,如果我們只是想處理純文本數(shù)據(jù),可以優(yōu)先考慮字符流,除此之外盡量使用字節(jié)流。
3. 節(jié)點流與處理流
另外如果從IO流的功能角度來看,IO流可以分為節(jié)點流和處理流,兩者有以下區(qū)別。
節(jié)點流,可以直接與數(shù)據(jù)源相連,進行讀入或寫出。
但如果我們直接使用節(jié)點流進行操作,讀寫并不方便,所以為了更快的讀寫文件,就有了處理流。
處理流,一般會與節(jié)點流一起使用,在節(jié)點流的基礎上,再套接一層,套接在節(jié)點流上的就是處理流。
四. 使用場景
總之,Java中有種類豐富且功能強大的IO流機制,包含了多種流類型,例如:字節(jié)流、字符流、緩沖流、數(shù)據(jù)流、對象流等。我們利用這些流,可以進行文件讀寫、網(wǎng)絡傳輸、圖片處理、音頻視頻處理等場景。
五. 結語
至此,就在今天的這篇文章中給大家科普了IO流的基本概念,今天的重點如下:
- IO流是一種流式的數(shù)據(jù)輸入/輸出模型,負責在數(shù)據(jù)源和目的地之間搭建一個傳輸通道,用于處理設備與代碼程序之間的數(shù)據(jù)傳輸;
- 輸入與輸出都是針對內(nèi)存而言的;
- 字節(jié)流是以字節(jié)(8bit)為單位進行數(shù)據(jù)的按序傳輸,一次讀取或寫入一個字節(jié)(8位)的二進制數(shù)據(jù);
- 字符流以字符為單位進行數(shù)據(jù)的按序傳輸,根據(jù)碼表映射字符,一次讀取或寫入一個字符(可能是多個字節(jié))。
以上就是學習Java之IO流的基礎概念詳解的詳細內(nèi)容,更多關于Java IO流的資料請關注腳本之家其它相關文章!
相關文章
基于Java代碼實現(xiàn)游戲服務器生成全局唯一ID的方法匯總
我們在做服務器系統(tǒng)開發(fā)的時候,為了適應數(shù)據(jù)大并發(fā)的請求,需要插入數(shù)據(jù)庫之前生成一個全局的唯一id,糾結全局唯一id怎么生成呢?下面小編給大家分享Java代碼實現(xiàn)游戲服務器生成全局唯一ID的方法匯總,涉及到優(yōu)劣勢方面的知識點,對此感興趣的朋友一起看看吧2016-10-10解決報java.lang.AssertionError錯誤的問題
這篇文章主要介紹了解決報java.lang.AssertionError錯誤的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05使用Spring Security集成手機驗證碼登錄功能實現(xiàn)
本文詳細介紹了如何利用SpringSecurity來實現(xiàn)手機驗證碼的注冊和登錄功能,在登錄過程中,同樣需通過驗證碼進行驗證,文章還提供了相關的代碼實現(xiàn)2024-10-10java基于正則表達式實現(xiàn)時間日期的常用判斷操作實例
這篇文章主要介紹了java基于正則表達式實現(xiàn)時間日期的常用判斷操作,簡單說明了正則表達式常用元字符含義并結合實例形式分析了java基于正則表達式針對常用日期時間格式的判斷操作技巧,需要的朋友可以參考下2017-10-10