java基礎(chǔ)——IO

I/O作為作為人機(jī)交互的核心問(wèn)題建峭,很多web應(yīng)用系統(tǒng)的瓶頸都是I/O瓶頸。本文主要總結(jié)java的I/O類(lèi)庫(kù)基本架構(gòu)以及磁盤(pán)I/O、網(wǎng)絡(luò)I/O工作機(jī)制裂明。

1. 基礎(chǔ)概念

編程語(yǔ)言I/O類(lèi)庫(kù)常使用流這個(gè)抽象概念,流是一個(gè)數(shù)據(jù)序列太援,有順序的闽晦,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偝苫虺橄筇岵怼仙蛉!傲鳌逼帘瘟藢?shí)際I/O設(shè)備中處理數(shù)據(jù)的細(xì)節(jié)。
流可不同維度進(jìn)行分類(lèi):

按數(shù)據(jù)傳輸單位:
字節(jié)流:每次讀到一個(gè)字節(jié)就返回一個(gè)字節(jié)碱蒙,可以處理所有類(lèi)型的數(shù)據(jù)對(duì)應(yīng)基類(lèi)InputStream和OutputStream
字符流:每次讀到一個(gè)字符(1個(gè)或多個(gè)字節(jié):中文對(duì)應(yīng)的字節(jié)數(shù)是兩個(gè)荠瘪,在UTF-8碼表中是3個(gè)字節(jié)),先去查指定的編碼表赛惩,將查到的字符返回哀墓。字符流是對(duì)字節(jié)流進(jìn)行了封裝,方便操作喷兼。在底層篮绰,所有的輸入輸出都是字節(jié)形式的,對(duì)應(yīng)基類(lèi)Write和Reader季惯。

按數(shù)據(jù)處理方向
輸入流:只能從中讀取數(shù)據(jù)吠各,由InputStream(字節(jié)流)和Reader(字符流)作為基類(lèi)
輸出流:只能向其寫(xiě)入數(shù)據(jù),由OutputStream(字節(jié)流)和Writer(字符流)作為基類(lèi)

2. java I/O類(lèi)庫(kù)

java I/O類(lèi)庫(kù)關(guān)系

功能劃分

  • File關(guān)聯(lián)類(lèi):FileReader, FileWriter, FileInputStream and FileOutputStream.
  • Array關(guān)聯(lián)類(lèi):ByteArrayInputStream, ByteArrayOutputStream / CharArrayReader, CharArrayWriter.
  • String關(guān)聯(lián)類(lèi):StringReader and StringWriter
  • Buffer關(guān)聯(lián)類(lèi):BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter
  • 字節(jié)流和字符流轉(zhuǎn)換橋梁:**InputStreamReader ** 和 OutputStreamWriter

IO流操作的基本步驟:

  1. open(創(chuàng)建一個(gè)輸入或輸出流關(guān)聯(lián)具體設(shè)備(網(wǎng)絡(luò)星瘾、磁盤(pán)等))
  2. read/write(從輸入流讀取數(shù)據(jù)或像輸出流寫(xiě)入數(shù)據(jù))
  3. close(關(guān)閉輸入或輸出流)

磁盤(pán)IO工作機(jī)制示意圖

磁盤(pán)IO讀流程

上述流程示例代碼

String src = "/Users/chenchen/code/java/Person.txt";
String dest = "/Users/chenchen/code/java/file.txt";
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {    
        in = new BufferedInputStream(new FileInputStream(src));    
        out = new BufferedOutputStream(new FileOutputStream(dest)); 
        byte[] files = new byte[1024];    
        int tmp = 0;    
        while ((tmp = in.read(files)) != -1){        
             out.write(files, 0, tmp);    
        }
} catch (Exception e) {    
        e.printStackTrace();
} finally {    
        try {        
               in.close();        
               out.close();    
        } catch (IOException e) {        
              e.printStackTrace();    
       }
}

建議所有磁盤(pán)相關(guān)IO操作使用Buffer
磁盤(pán)設(shè)備由操作系統(tǒng)管理走孽,所以磁盤(pán)相關(guān)讀取和寫(xiě)入IO操作都是調(diào)用操作系統(tǒng)提供的接口。系統(tǒng)調(diào)用就可能存在內(nèi)核空間地址和用戶(hù)空間地址切換的問(wèn)題琳状,這個(gè)操作在保證安全性同時(shí)導(dǎo)致多余的耗時(shí)磕瓷。讀寫(xiě)單個(gè)byte就顯得很耗費(fèi)時(shí)間,IO類(lèi)庫(kù)提供了Buffer相關(guān)的類(lèi)來(lái)加速I(mǎi)O操作。

3. 序列化

java序列化就是將一個(gè)對(duì)象轉(zhuǎn)換成一串二進(jìn)制表示的字節(jié)數(shù)組困食,通過(guò)轉(zhuǎn)移或者保存這些數(shù)據(jù)達(dá)到持久化的目的边翁。反序列化必須有該類(lèi)的原始模板,才能達(dá)到還原該對(duì)象的目的硕盹。需要進(jìn)行序列化的對(duì)象只需要實(shí)現(xiàn)Seriaizable接口

3.1 什么時(shí)候需要序列化

  • 當(dāng)你想把的內(nèi)存中的對(duì)象保存到一個(gè)文件中或者數(shù)據(jù)庫(kù)中時(shí)候符匾;
  • 當(dāng)你想用套接字在網(wǎng)絡(luò)上傳送對(duì)象的時(shí)候;
  • 當(dāng)你想通過(guò)RMI傳輸對(duì)象的時(shí)候瘩例;

3.2 關(guān)于java序列化幾點(diǎn)說(shuō)明

  1. 當(dāng)一個(gè)父類(lèi)實(shí)現(xiàn)序列化啊胶,子類(lèi)自動(dòng)實(shí)現(xiàn)序列化,不需要顯式實(shí)現(xiàn)Serializable接口垛贤;
  2. 如果序列化的屬性是對(duì)象焰坪,則這個(gè)對(duì)象也必須實(shí)現(xiàn)Serializable接口,否則會(huì)報(bào)錯(cuò)聘惦;
  3. static,transient后的變量不能被序列化某饰;
  4. 反序列化過(guò)程中,如果對(duì)象的屬性有修改或刪減善绎,相應(yīng)屬性的值會(huì)丟失黔漂。

serialVersionUID說(shuō)明
如果沒(méi)有明確指定serialVersionUID,序列化的時(shí)候會(huì)根據(jù)字段和特定的算法生成一個(gè)serialVersionUID禀酱,當(dāng)屬性有變化時(shí)這個(gè)id發(fā)生了變化炬守,所以反序列化的時(shí)候就會(huì)失敗。拋出“本地classd的唯一id和流中class的唯一id不匹配”剂跟。
強(qiáng)烈建議 所有可序列化類(lèi)都顯式聲明 serialVersionUID 值劳较,原因是計(jì)算默認(rèn)的 serialVersionUID 對(duì)類(lèi)的詳細(xì)信息具有較高的敏感性,根據(jù)編譯器實(shí)現(xiàn)的不同可能千差萬(wàn)別浩聋,這樣在反序列化過(guò)程中可能會(huì)導(dǎo)致意外的 InvalidClassException。
同時(shí)強(qiáng)烈建議使用 private 修飾符顯示聲明 serialVersionUID(如果可能)臊恋,原因是這種聲明僅應(yīng)用于直接聲明類(lèi) -- serialVersionUID 字段作為繼承成員沒(méi)有用處

3.3 java序列化對(duì)應(yīng)IO類(lèi)

java.io.ObjectOutputStream:表示對(duì)象輸出流它的writeObject(Object obj)方法可以對(duì)參數(shù)指定的obj對(duì)象進(jìn)行序列化衣洁,把得到的字節(jié)序列寫(xiě)到一個(gè)目標(biāo)輸出流中。
java.io.ObjectInputStream:表示對(duì)象輸入流它的readObject()方法源輸入流中讀取字節(jié)序列抖仅,再把它們反序列化成為一個(gè)對(duì)象坊夫,并將其返回。
示例代碼如下:

TestModel testModel = new TestModel();
Person person = new Person();
person.setName("cc");
person.setAge(12);
testModel.setPerson(person);
testModel.setId(1);
ObjectOutputStream out = null;
ObjectInputStream in = null;
try {    
    // 序列化    
    out = new ObjectOutputStream(new FileOutputStream("test.txt")); 
    out.writeObject(testModel);    
    // 反序列化    
    in = new ObjectInputStream(new FileInputStream("test.txt"));  
    TestModel result = (TestModel)in.readObject();
    }catch (Exception e){    
        e.printStackTrace();
    } finally {    
        try {       
             out.close();        
             in.close();    
    } catch (IOException e) {    
    }
}

示例中TestModel實(shí)現(xiàn)了Serializable接口撤卢,同時(shí)其引用屬性Person也要實(shí)現(xiàn)Serializable接口否則會(huì)報(bào)錯(cuò)环凿。

參考文檔

https://www.ntu.edu.sg/home/ehchua/programming/java/J5b_IO.html
http://www.devinline.com/2015/10/internal-details-of-java-IO-classes.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市放吩,隨后出現(xiàn)的幾起案子智听,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件到推,死亡現(xiàn)場(chǎng)離奇詭異考赛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)莉测,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)颜骤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捣卤,你說(shuō)我怎么就攤上這事忍抽。” “怎么了董朝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵鸠项,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我益涧,道長(zhǎng)锈锤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任闲询,我火速辦了婚禮久免,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扭弧。我一直安慰自己阎姥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布鸽捻。 她就那樣靜靜地躺著呼巴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪御蒲。 梳的紋絲不亂的頭發(fā)上衣赶,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音厚满,去河邊找鬼府瞄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碘箍,可吹牛的內(nèi)容都是我干的遵馆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼丰榴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼货邓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起四濒,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤换况,失蹤者是張志新(化名)和其女友劉穎职辨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體复隆,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拨匆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挽拂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惭每。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖亏栈,靈堂內(nèi)的尸體忽然破棺而出媒熊,到底是詐尸還是另有隱情父丰,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站荤懂,受9級(jí)特大地震影響闯参,放射性物質(zhì)發(fā)生泄漏惊奇。R本人自食惡果不足惜烙样,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脐往。 院中可真熱鬧休吠,春花似錦、人聲如沸业簿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梅尤。三九已至柜思,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巷燥,已是汗流浹背赡盘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缰揪,地道東北人亡脑。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像邀跃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛙紫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

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

  • JAVA序列化機(jī)制的深入研究 對(duì)象序列化的最主要的用處就是在傳遞,和保存對(duì)象(object)的時(shí)候,保證對(duì)象的完整...
    時(shí)待吾閱讀 10,872評(píng)論 0 24
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法拍屑,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法坑傅,繼承相關(guān)的語(yǔ)法僵驰,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,664評(píng)論 18 399
  • 1. 流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中蒜茴,管道是一條不間斷的字節(jié)...
    JackChen1024閱讀 825評(píng)論 0 10
  • 讀書(shū)到底是為了什么星爪,如果我們排除做學(xué)問(wèn)很實(shí)際的目的,讀書(shū)就是我在吸取營(yíng)養(yǎng)粉私,把自己豐富起來(lái)顽腾。我自己感覺(jué),讀書(shū)最愉快的...
    篤學(xué)青衿閱讀 150評(píng)論 0 0
  • 午間分享[玫瑰][玫瑰][玫瑰] 事件發(fā)生經(jīng)過(guò):弟弟把姐姐的試卷畫(huà)的亂七八糟的漓摩,姐姐不開(kāi)心,弟弟不愿道歉入客。[尷尬]...
    如緣夏雨閱讀 301評(píng)論 0 0