IO流

# Java 流式輸入 輸出原理

# Java 流的分類

# 輸入 輸出 流 類

# 常見的節(jié)點(diǎn)流 和 處理流

# 文件流

# 緩沖流

# 數(shù)據(jù)流

# 轉(zhuǎn)換流

# Print流

# Object 流

Java 流式輸入 輸出 原理

在Java程序中 對于數(shù)據(jù)的輸入 輸出操作以 流 stream方式進(jìn)行,J2SDK 提供了各種各樣的 流 類,用以獲取不同種類的數(shù)據(jù) 程序中通過標(biāo)準(zhǔn)的方法 輸入或輸出數(shù)據(jù)

File封裝的是文件的文件名箱叁,真正的文件是硬盤上的一塊空間,文件內(nèi)存著各種數(shù)據(jù),通過流的方式讀取文件內(nèi)的數(shù)據(jù)开泽。對于計算機(jī)而言,讀取計算機(jī)的文件都是0101魁瞪,

將文件 模擬成 一個桶? 讀取文件內(nèi)的數(shù)據(jù)穆律,可以通過 在桶上安裝一個管道,然后打開水龍頭 開始出水导俘, 這根管道就叫做流峦耘,Java里流式的輸入輸出 與水流的原理相同,從文件內(nèi)讀取數(shù)據(jù)時旅薄,安插一個管道讀取數(shù)據(jù)辅髓,寫數(shù)據(jù)時,往文件上插入管道,一直灌水洛口。

這個文件可以是硬盤上或者內(nèi)存里的文件矫付,也可以是網(wǎng)絡(luò)上的數(shù)據(jù),連接對方的某一端口第焰,有的時候 管道內(nèi)的水不是你想要的純凈水 有一些雜質(zhì) 需要過濾买优,這個時候需要 在外面再包一層管道,就是對0101字節(jié)數(shù)據(jù) 再進(jìn)行一些封裝挺举,轉(zhuǎn)換成字符串(管道)杀赢。流式原理中最重要的就是這些不同的管道。

Java流式輸入輸出原理

輸入 輸出流的分類:

java.io 包中定義了多個流類型(類或抽象類)實(shí)現(xiàn)輸入輸出功能豹悬,可以從不同角度對其進(jìn)行分類:

按照數(shù)據(jù)流的方向可以分為:輸入流和輸出流葵陵,按照處理數(shù)據(jù)的單位可以分為字節(jié)流和字符流液荸。按照功能不同可以分為節(jié)點(diǎn)流和處理流瞻佛。

J2SDK所提供的所有流類型位于Java.io內(nèi)都分別繼承自以下四種抽象流類型:


輸入 輸出流的分類

? ? ? ? ? ? ? ? ? ?字節(jié)流 ? ? ? ? ? ? ?字符流(四個抽象流)

輸入流 ? ? ? InputStream ? ? ?Reader

輸出流 ? ? ? OutputStream ? ?Writer

接入文件讀取文件的數(shù)據(jù),針對文件而言是輸出娇钱,針對程序而言是輸入伤柄,我們是從程序的角度出發(fā)。

字節(jié)流:讀出的數(shù)據(jù)是010101 ?8位一個字節(jié)的讀取文搂。

字符流:一個字符 一個字符 兩個字節(jié)的處理? Java是unicode字符串 ?UTF-16

節(jié)點(diǎn)流和處理流

節(jié)點(diǎn)流:管道直接連接到數(shù)據(jù)源适刀,即可以從一個特定的數(shù)據(jù)源(節(jié)點(diǎn))讀寫數(shù)據(jù)。(如 文件 內(nèi)存)

處理流:如果對原始的節(jié)點(diǎn)流 處理的不合適 可以在流處理時 ?套入其他管道煤蹭,即“”“連接”在已存在的流(節(jié)點(diǎn)流或處理流)之上笔喉,通過對數(shù)據(jù)的處理為程序員提供更為強(qiáng)大的讀寫功能。 ?水流里有雜質(zhì)硝皂,一層層過濾 處理常挚,針對數(shù)據(jù)提供更高級的處理,更強(qiáng)大的讀寫功能稽物。

InputStream


字節(jié)流輸入子類圖

繼承自InputStream(抽象類)的流都是用于向程序中輸入數(shù)據(jù)奄毡,且數(shù)據(jù)的單位為字節(jié)(8bit),深色為節(jié)點(diǎn)流贝或,淺色為處理流吼过。ObjectInputStream ?把對象從字節(jié)流里讀取出來,涉及到對象的序列化咪奖。

InputStream的基本方法:


InputStream 基本方法

int read() throws IOException ?// 讀取一個字節(jié)并以整數(shù)形式返回 0-255盗忱,如果返回-1就到輸入流的末尾 ?每次讀取一個字節(jié) 每次讀取一個字節(jié)

int read(byte[] buffer) throws IOException // 讀取一系列字節(jié)并存儲到一個數(shù)組Buffer(內(nèi)存中的緩沖區(qū)),返回實(shí)際讀取的字節(jié)數(shù)羊赵,如果讀取前已到輸入流的末尾返回-1 ? 將buffer字節(jié)數(shù)組填滿數(shù)據(jù)之后趟佃,再進(jìn)行處理。 電驢 下載 p2p軟件比較毀硬盤,讀取比較頻繁揖闸,容易損傷揍堕,不能每次讀取一個字節(jié)訪問一次硬盤。在內(nèi)存里開辟一個空間汤纸,讀一次硬盤將該空間(字節(jié)數(shù)組)裝滿衩茸,大大減少對硬盤的訪問次數(shù)。寫的時候贮泞,將該空間填滿楞慈,再一次性寫進(jìn)硬盤。減少對硬盤的訪問次數(shù)啃擦。

int read(byte[] buffer,int offset,int length) throws IOException ?// 讀取length個字節(jié)囊蓝,并存儲到一個字節(jié)數(shù)組buffer 從offset位置開始 返回實(shí)際讀取的字節(jié)數(shù) 如果讀取前已到輸入流的末尾返回-1

void close() throws IOException // 關(guān)閉流釋放內(nèi)存資源

long skip(long n) throws IOException // 跳過n個字節(jié)不讀,返回實(shí)際跳過的字節(jié)數(shù)

OutputStream:


OutputStream

繼承自O(shè)utputStream的流是用于程序中輸入數(shù)據(jù)令蛉,且數(shù)據(jù)的單位為字節(jié)(8bit):深色為節(jié)點(diǎn)流聚霜、淺色為處理流。

OutputStream的基本方法


OutputStream 基本方法

void write(int b) throws IOException // 向輸出流寫入一個字節(jié)數(shù)據(jù)珠叔,該字節(jié)數(shù)據(jù)為參數(shù)b的低8位

void write(byte[] b) throws IOException // 將一個字節(jié)類型的數(shù)組中的數(shù)據(jù)寫入輸出流

void write(byte[] b,int off,int len) throws IOException // 將一個字節(jié)類型的數(shù)組從指定位置off 開始的len個字節(jié)寫入到輸出流

void close() throws IOException // 關(guān)閉流釋放內(nèi)存資源

void flush() throws IOException // 將輸出流中緩沖的數(shù)據(jù)全部寫到目的地


close之前需要flush

close 之前調(diào)用flush蝎宇,close比較粗暴 直接關(guān)閉流釋放了內(nèi)存資源,假如此時緩沖區(qū)尚有部分?jǐn)?shù)據(jù)為通過“管道”寫入到目的地祷安。

Reader:

繼承自Reader的流都是用于向程序中輸入數(shù)據(jù)姥芥,且數(shù)據(jù)的單位為字符,兩個字節(jié)汇鞭,16bit凉唐,下圖中深色為節(jié)點(diǎn)流,淺色為處理流霍骄。

Reader

中文字符在Java 中是兩個字節(jié)的存在台囱,為了保障其能正常顯示,必須一個字符一個字符即兩個字節(jié)兩個字節(jié)的讀取腕巡。

Reader的基本方法:


Reader的基本方法

int read() throws IOException? // 讀取一個字符并以整數(shù)形式返回 0-255玄坦,如果返回-1就到輸入流的末尾? 每次讀取一個字符?每次讀取一個字符

int read(char[] cbuffer) throws IOException // 讀取一系列字符并存儲到一個數(shù)組Buffer(內(nèi)存中的緩沖區(qū)),返回實(shí)際讀取的字符數(shù)绘沉,如果讀取前已到輸入流的末尾返回-1 ? 將buffer字符數(shù)組填滿數(shù)據(jù)之后煎楣,再進(jìn)行處理。

int read(char[] cbuffer,int offset,int length) throws IOException ?// 讀取length個字符车伞,并存儲到一個字符數(shù)組buffer 從offset位置開始 返回實(shí)際讀取的字符數(shù) 如果讀取前已到輸入流的末尾返回-1

void close() throws IOException // 關(guān)閉流釋放內(nèi)存資源

long skip(long n) throws IOException // 跳過n個字節(jié)不讀择懂,返回實(shí)際跳過的字符數(shù)

Writer:

繼承自Writer的流都是用于從程序中輸出數(shù)據(jù),且數(shù)據(jù)的單位為字符另玖,兩個字節(jié)困曙,16bit表伦,下圖中深色為節(jié)點(diǎn)流,淺色為處理流慷丽。


Writer的基本方法

Writer的基本方法

void write(int c) throws IOException // 向輸出流寫入一個字符數(shù)據(jù)蹦哼,該字符數(shù)據(jù)為參數(shù)b的低16位

void write(char[] cbuf) throws IOException // 將一個字符類型的數(shù)組中的數(shù)據(jù)寫入輸出流

void write(char[] cbuf,int off,int len) throws IOException // 將一個字符類型的數(shù)組從指定位置off 開始的len個字符寫入到輸出流

void write(String string) throws IOException // 將一個字符串中的字符寫入輸出流

void write(String string,int off,int len) throws IOException // 將一個字符串從off開始的len個字符寫入到輸出流

void close() throws IOException // 關(guān)閉流釋放內(nèi)存資源

void flush() throws IOException // 將輸出流中緩沖的數(shù)據(jù)全部寫到目的地

節(jié)點(diǎn)流類型:

節(jié)點(diǎn)流

節(jié)點(diǎn)流:直接處理數(shù)據(jù)源數(shù)據(jù)的流類,直接處理文件 內(nèi)存里的數(shù)組 內(nèi)存里的String 以及管道(線程和線程之間通信)


訪問文件

訪問文件:

FileInputStream 和 FileOutputStream 分別繼承自InputStream和OutputStream,用于向文件中輸入或輸出字節(jié)要糊。

FileInputStream和FileOutputStream 常用構(gòu)造方法:

FileInputStream(String name) throws FileNotFoundException

FileInputStream(File file) throws FileNotFoundException

FileOutputStream(String name) throws FileNotFoundException

FileOutputStream(File file) throws FileNotFoundException (無文件會自動創(chuàng)建該文件 只能建文件 不能建目錄)

FileOutputStream(File file,Boolean append) throws FileNotFoundException

FileInputStream和FileOutputStream類支持其父類InputStream和OutputStream所提供的數(shù)據(jù)讀寫方法

注意:在實(shí)例化FileInputStream和FileOutputStream實(shí)例要try-catch 語句以處理其可能拋出的FileNotFoundException纲熏。在讀寫數(shù)據(jù)時也要用try-catch 語句以處理可能拋出的IOException,是其子類锄俄。

\\ 是window下在Java程序中定義的路徑分隔符 ?或者 ?/ ? ?正斜杠

以字節(jié)形式讀取字符數(shù)據(jù)的話 ?無法轉(zhuǎn)換成功 ?用Reader讀取 ?也可能是編碼格式問題


處理流:

處理流

處理節(jié)點(diǎn)流或處理流的返回的數(shù)據(jù)局劲,相當(dāng)于對數(shù)據(jù)進(jìn)行多層封裝。


緩沖流

緩沖流要“”“套接在”相應(yīng)的節(jié)點(diǎn)流上奶赠,對讀寫的數(shù)據(jù)提供了緩沖的功能鱼填,提高了讀寫的效率,同時增加了一些新的方法毅戈。四種緩沖流苹丸,常用構(gòu)造:

BufferedReader(Reader in)

BufferedReader(Reader in,int sz) // sz為自定義緩存區(qū)的大小

BufferedWriter(Writer out)

BufferedWriter(Writer out,int sz)

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int sz)

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int size)

緩沖輸入流支持其父類的mark和reset方法

BufferedReader提供了readLine方法用于讀取一行字符串(以\r或\n分隔)

BufferedWriter提供了newLine用于寫入一個行分隔符

對于輸出的緩沖流,寫出的數(shù)據(jù)會先在內(nèi)存中緩存竹祷,使用flush方法將會使內(nèi)存中的數(shù)據(jù)立刻寫出谈跛。


處理流與節(jié)點(diǎn)流(字節(jié))的管道封裝


處理流與節(jié)點(diǎn)流(字符)的管道封裝

轉(zhuǎn)換流:

字節(jié)到字符的轉(zhuǎn)換流

字節(jié)流轉(zhuǎn)換為字符流羊苟,InputStreamReader和OutputStreamWriter用于字節(jié)數(shù)據(jù)到字符數(shù)據(jù)知己恩的轉(zhuǎn)換塑陵。InputStreamReader需要和InutStream進(jìn)行“”“套接”,OutputStreamWriter需要和OutputStream“套接”蜡励,轉(zhuǎn)換流在構(gòu)造時可以指定其編碼集合令花,比如: InputStream isr = new InputStreamReader(System.in,"ISO8859_1");

中文window默認(rèn)編碼 gbk


轉(zhuǎn)換流

可以直接寫中文和String,比較好用凉倚。


字節(jié)轉(zhuǎn)字符進(jìn)行緩沖流處理

首先 字節(jié)(阻塞式方法兼都、同步方法 System.in)轉(zhuǎn)字符 然后進(jìn)行緩沖流處理。

數(shù)據(jù)流

DataInputStream和DataOutputStream分別繼承自InputStream和outputStream,屬于處理流稽寒,需要分別套接在InputStream和OutputStream類型的節(jié)點(diǎn)流上扮碧。

DataInputStream和DataOutputStream提供了可以存取與機(jī)器無關(guān)的原始類型數(shù)據(jù)(int double)等方法

DataInputStream和DataOutputStream的構(gòu)造方法:

DataInputStream(InputStream in)

DataOutputStream(OutputStream in)

網(wǎng)絡(luò)上傳輸數(shù)據(jù)時 ?經(jīng)常使用ReadUTF() ?utf-8 比較省空間 網(wǎng)絡(luò)上用的比較多

數(shù)據(jù)流

直接操作原始數(shù)據(jù)類型的數(shù)據(jù)讀寫,比較方便好用杏糙。

先寫的先讀慎王。new DataOutputStream(new ByteArrayOutputStream())

.writeDouble(Math.random()) ?// 內(nèi)存中占8個字節(jié) 可以同DataOutputStream直接寫入

.writeBoolean(true) // 內(nèi)存中占1個字節(jié)

new DataInputStream(new ByteArrayInputStream(baos.toByteArray()))

.readDouble() ?// 先寫的先讀 ?或者容易出現(xiàn)亂碼

.readBoolean()

基本數(shù)據(jù)類型數(shù)據(jù) 的直接寫入 與ByteArrayInutStream的結(jié)合

Print 流 只有輸出流

自動flush,PrintWriter 和 PrintStream 輸出操作不會拋出異常宏侍。用戶通過檢測錯誤狀態(tài)獲取錯誤信息赖淤。


PrintStream重定向

Object流 -- 序列化(標(biāo)記型接口 給編譯器看) 外部化 transient 保存和傳遞 對象狀態(tài)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谅河,隨后出現(xiàn)的幾起案子咱旱,更是在濱河造成了極大的恐慌确丢,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吐限,死亡現(xiàn)場離奇詭異鲜侥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诸典,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門剃毒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搂赋,你說我怎么就攤上這事赘阀。” “怎么了脑奠?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵基公,是天一觀的道長。 經(jīng)常有香客問我宋欺,道長轰豆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任齿诞,我火速辦了婚禮酸休,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祷杈。我一直安慰自己斑司,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布但汞。 她就那樣靜靜地躺著宿刮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪私蕾。 梳的紋絲不亂的頭發(fā)上僵缺,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機(jī)與錄音踩叭,去河邊找鬼磕潮。 笑死,一個胖子當(dāng)著我的面吹牛容贝,可吹牛的內(nèi)容都是我干的自脯。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼嗤疯,長吁一口氣:“原來是場噩夢啊……” “哼冤今!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茂缚,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤戏罢,失蹤者是張志新(化名)和其女友劉穎屋谭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體龟糕,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桐磁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讲岁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片我擂。...
    茶點(diǎn)故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缓艳,靈堂內(nèi)的尸體忽然破棺而出校摩,到底是詐尸還是另有隱情,我是刑警寧澤阶淘,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布衙吩,位于F島的核電站,受9級特大地震影響溪窒,放射性物質(zhì)發(fā)生泄漏坤塞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一澈蚌、第九天 我趴在偏房一處隱蔽的房頂上張望摹芙。 院中可真熱鬧,春花似錦宛瞄、人聲如沸浮禾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伐厌。三九已至,卻和暖如春裸影,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背军熏。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工轩猩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荡澎。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓均践,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摩幔。 傳聞我的和親對象是個殘疾皇子彤委,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評論 2 349

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