java.io源碼解析(一)--字節(jié)流(InputStream黔帕、OutputStream)字符流(Reader代咸、Writer)

聲明:本系列只供本人自學(xué)使用,勿噴成黄。

IO是每位java工程師都必須掌握的知識(shí)點(diǎn)呐芥,無論什么項(xiàng)目都會(huì)涉及文件IO、網(wǎng)絡(luò)IO等慨默,但是java中的IO類多達(dá)幾十種贩耐,很多人在使用時(shí)會(huì)難以抉擇,并且網(wǎng)上關(guān)于IO的學(xué)習(xí)資料比較雜亂厦取,因此本人決定研究JDK8中rt.jar的java.io源碼并總結(jié)為系列文章,如有不正之處還請(qǐng)多多指點(diǎn)管搪。

網(wǎng)上的IO教程大多是一上來就扔個(gè)降視力的大圖虾攻,嚇得我等小白直接X掉網(wǎng)頁。本人痛定思痛更鲁,決定從0擴(kuò)展IO體系霎箍,首先我們按照操作單元進(jìn)行劃分,如下圖澡为。

程序中的所有數(shù)據(jù)都是以流的方式存儲(chǔ)或傳輸漂坏,通常情況下,二進(jìn)制數(shù)據(jù)(Binary)使用字節(jié)流傳輸、存儲(chǔ)顶别,文本數(shù)據(jù)(ASCII)使用字符流傳輸谷徙、存儲(chǔ)、讀取驯绎。

一完慧、字節(jié)流

1.InputStream

  • 源碼結(jié)構(gòu)圖
  • 核心方法

核心方法就是read,讀取InputStream并保存到byte[]

// 返回下一個(gè)字節(jié)剩失,如果沒有則返回-1
public abstract int read() throws IOException

// 實(shí)際調(diào)用read(b, 0, b.length);
public int read(byte b[]) throws IOException

public int read(byte b[], int off, int len) throws IOException{
    1.參數(shù)檢查
    2.循環(huán)read()屈尼,賦值給b
    3.返回上一步賦值給b的字節(jié)數(shù)量
}

public void close() throws IOException
  • 其余方法
// 跳過n個(gè)字節(jié)
public long skip(long n) throws IOException{
    1. size=(常量MAX_SKIP_BUFFER_SIZE與入?yún)的較小值)
    2. 循環(huán)read()賦值給臨時(shí)數(shù)組new byte[size]
}
// 返回InputStream的字節(jié)數(shù),但是并不準(zhǔn)確
public int available() throws IOException

// 標(biāo)記拴孤,回到標(biāo)記位脾歧,是否支持該功能
public synchronized void mark(int readlimit) 
public synchronized void reset() throws IOException
public boolean markSupported() 

2.OutputStream

  • 源碼結(jié)構(gòu)圖
  • 核心方法

核心方法就是write,將byte[]寫入OutputStream

public abstract void write(int b) throws IOException;

// 實(shí)際調(diào)用write(b, 0, b.length);
public void write(byte b[]) throws IOException

public void write(byte b[], int off, int len) throws IOException{
    1.參數(shù)檢查
    2.循環(huán)write() 
}

// 保證字節(jié)數(shù)組傳遞給底層操作系統(tǒng)演熟,不能保證操作系統(tǒng)已完成寫入
public void flush() throws IOException

public void close() throws IOException

二鞭执、字符流

1.Reader

  • 源碼結(jié)構(gòu)圖


  • 構(gòu)造器
// 用來實(shí)現(xiàn)同步操作,子類如果需要同步绽媒,也應(yīng)使用synchronized (lock)
protected Object lock;

protected Reader() {
    this.lock = this;
}

protected Reader(Object lock) {
    if (lock == null) {
        throw new NullPointerException();
    }
    this.lock = lock;
}
  • 核心方法

核心方法就是read蚕冬,讀取Reader并保存到char[]

// 返回下一個(gè)字符,如果沒有則返回-1
public int read() throws IOException 

// 實(shí)際調(diào)用read(cbuf, 0, cbuf.length);
public int read(char cbuf[]) throws IOException

abstract public int read(char cbuf[], int off, int len) throws IOException

//JDK5新增
public int read(java.nio.CharBuffer target) throws IOException{
    1.讀取target.remaining()個(gè)字符到char[]
    2.將char[]賦值給target
}

public void close() throws IOException
  • 其余方法
// 跳過n個(gè)字節(jié)
public long skip(long n) throws IOException{
    1. size=(常量maxSkipBufferSize與入?yún)的較小值)
    2. 循環(huán)read()賦值給臨時(shí)數(shù)組new byte[size]
}
// 下一次read()是否阻塞
public boolean ready() throws IOException

// 標(biāo)記是辕,回到標(biāo)記位囤热,是否支持該功能
public synchronized void mark(int readlimit) 
public synchronized void reset() throws IOException
public boolean markSupported() 

2.Writer

  • 源碼結(jié)構(gòu)圖


  • 構(gòu)造器(同Reader)
// 用來實(shí)現(xiàn)同步操作,子類如果需要同步获三,也應(yīng)使用synchronized (lock)
protected Object lock;

protected Writer() {
    this.lock = this;
}

protected Writer(Object lock) {
    if (lock == null) {
        throw new NullPointerException();
    }
    this.lock = lock;
}
  • 核心方法

核心方法
① write旁蔼,將char[] 寫入Writer
② append,將CharSequence追加到Writer

// 以下方法實(shí)際調(diào)用write(char cbuf[], int off, int len)
public void write(int c) throws IOException
public void write(char cbuf[]) throws IOException
public void write(String str) throws IOException
public void write(String str, int off, int len) throws IOException
//JDK5新增
public Writer append(CharSequence csq) throws IOException
public Writer append(CharSequence csq, int start, int end) throws IOException
public Writer append(char c) throws IOException

abstract public void write(char cbuf[], int off, int len) throws IOException;

// 保證字符數(shù)組傳遞給底層操作系統(tǒng)疙教,不能保證操作系統(tǒng)已完成寫入
public void flush() throws IOException

public void close() throws IOException

三棺聊、總結(jié)

  • 字節(jié)流通過字節(jié)數(shù)組byte[]進(jìn)行讀寫操作,InputStream核心方法是read(byte b[], int off, int len)贞谓,OutputStream核心方法是write(byte b[], int off, int len)
  • 字符流通過字符數(shù)組char[]進(jìn)行讀寫操作限佩,Reader核心方法是read(char cbuf[], int off, int len),Writer核心方法是write(char cbuf[], int off, int len)
  • 無論讀取哪種流裸弦,read返回值為-1表示結(jié)束祟同,其他值則表示已讀取到數(shù)組中的數(shù)量。

本節(jié)討論的類都是抽象類理疙,力求從宏觀上了解這些類各自的作用晕城,接下來的系列將深入具體的實(shí)現(xiàn)類源碼,并用簡(jiǎn)單demo示例進(jìn)行說明窖贤。由于輸入流砖顷、輸出流代碼相似贰锁,并且在使用時(shí)一般都成對(duì)出現(xiàn),下文也將成對(duì)講解滤蝠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豌熄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子几睛,更是在濱河造成了極大的恐慌房轿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件所森,死亡現(xiàn)場(chǎng)離奇詭異囱持,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)焕济,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門纷妆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晴弃,你說我怎么就攤上這事掩幢。” “怎么了上鞠?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵际邻,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我芍阎,道長(zhǎng)世曾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任谴咸,我火速辦了婚禮轮听,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岭佳。我一直安慰自己血巍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布珊随。 她就那樣靜靜地躺著述寡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叶洞。 梳的紋絲不亂的頭發(fā)上辨赐,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音京办,去河邊找鬼。 笑死帆焕,一個(gè)胖子當(dāng)著我的面吹牛惭婿,可吹牛的內(nèi)容都是我干的不恭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼财饥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼换吧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钥星,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤沾瓦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谦炒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贯莺,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年宁改,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缕探。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡还蹲,死狀恐怖爹耗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谜喊,我是刑警寧澤潭兽,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站斗遏,受9級(jí)特大地震影響山卦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜最易,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一怒坯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藻懒,春花似錦剔猿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鄙早,卻和暖如春汪茧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背限番。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工舱污, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弥虐。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓扩灯,卻偏偏與公主長(zhǎng)得像媚赖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子珠插,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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

  • 前提 參考資料: 《Java I/O》 -- 這本書沒有翻譯版惧磺,需要自己啃一下。 《Java I/O》這本書主要介...
    zhrowable閱讀 1,175評(píng)論 0 1
  • 五捻撑、IO流 1磨隘、IO流概述 (1)用來處理設(shè)備(硬盤,控制臺(tái)顾患,內(nèi)存)間的數(shù)據(jù)番捂。(2)java中對(duì)數(shù)據(jù)的操作都是通過...
    佘大將軍閱讀 508評(píng)論 0 0
  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序運(yùn)行的過程中,可能需要對(duì)一些設(shè)備進(jìn)...
    征程_Journey閱讀 962評(píng)論 0 1
  • 一描验、基礎(chǔ)知識(shí):1白嘁、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,379評(píng)論 0 4
  • 1.流的分類 (1)輸入輸出流輸入輸出是針對(duì)程序運(yùn)行的內(nèi)存而言的輸入流的基類:InputStream膘流,Reader...
    ql2012jz閱讀 580評(píng)論 0 3