????????慚愧,編程幾年一直沒有系統(tǒng)了解下IO流,做技術(shù)還是要踏踏實(shí)實(shí)的一步一個(gè)腳印慢慢積累,欺騙生活最終被欺騙的是你自己。
? ? ? ? 慣例來段概述,流是一組有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q或抽象。即數(shù)據(jù)在兩設(shè)備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸,根據(jù)數(shù)據(jù)傳輸特性將流抽象為各種類,方便更直觀的進(jìn)行數(shù)據(jù)操作。
? ? ? ? IO流分類上張圖

注:
????????1.此處的輸入,輸出是站在程序運(yùn)行內(nèi)存角度考慮的,輸入指向輸入到內(nèi)存,輸出指從內(nèi)存輸出
? ? ? ? 2.字節(jié)流和字符流的區(qū)別在于操作單元不同,字節(jié)流以字節(jié)(8bit)為單位,字符流以字符(16bit)為單位,Java中字符是采用Unicode標(biāo)準(zhǔn),一個(gè)字符是16位,為此,JAVA中引入了處理字符的流,其本質(zhì)其實(shí)就是基于字節(jié)流讀取時(shí),查詢指定碼表。
? ? ? ? IO流常用類以及各類所負(fù)責(zé)媒介再上張圖

1.輸入字節(jié)流InputStream
1) ? ?InputStream是所有的輸入字節(jié)流的抽象父類
2) ?ByteArrayInputStream、 FileInputStream是兩種基本的介質(zhì)流,它們分別從Byte數(shù)組、和本地文件中讀取數(shù)據(jù)
3) ? PipedInputStream是從與其它線程共用的管道中讀取數(shù)據(jù)
4.) ObjectInputStream和所有FilterInputStream的子類都是裝飾流(裝飾器模式的主角)
InputStream包含3個(gè)基本讀方法
??abstract?int read():讀取一字節(jié)數(shù)據(jù)并返回,返回-1表示讀到了輸入流的末尾
? int read(byte[] b):將數(shù)據(jù)讀入一個(gè)數(shù)組,同時(shí)返回實(shí)際讀取的字節(jié)數(shù),返回-1表示讀到了輸入流的末尾
??int read(byte[] b,int off,int len):將數(shù)據(jù)讀入一個(gè)字節(jié)數(shù)組,同時(shí)返回實(shí)際讀取的字節(jié)數(shù)。返回-1表示讀到了輸入流的末尾。off指定在數(shù)組b中存放數(shù)據(jù)的起始偏移位置;len指定讀取的最大字節(jié)數(shù)。
2.輸入字符流Reader
1)Reader是所有的輸入字符流的父類
2)CharArrayReader和StringReader是兩種基本介質(zhì)流,分別將Char數(shù)組和String中讀取數(shù)據(jù)
3)PipedReader是從與其他線程共用的管道中讀取數(shù)據(jù)
4)FilterReader是所有自定義具體裝飾流的父類,其子類PushbackReader對(duì)Reader對(duì)象進(jìn)行裝飾會(huì)增加一個(gè)行號(hào)
5)InputStreamReader:是Reader的子類,將輸入的字節(jié)流變?yōu)樽址?,即:將一個(gè)字節(jié)流的輸入對(duì)象變?yōu)樽址鞯妮斎雽?duì)象
Reader包含3個(gè)基本讀方法
? int read():讀取一個(gè)字符,返回值為讀取的字符
? int read(char[] b) :讀取一系列字符到數(shù)組char中,返回值為實(shí)際讀取的字符數(shù)量
??int read(char[] b,int off,int len):讀取len個(gè)字符,從數(shù)組char[]的下標(biāo)off處開始存放,返回值為實(shí)際讀取的字符數(shù)量
InputStream和Reader移動(dòng)指針的方法:
? void mark(int readlimit):在輸入流當(dāng)前位置放置一個(gè)標(biāo)記,如果讀取的字節(jié)數(shù)多于readlimit設(shè)置的值,則流忽略這個(gè)標(biāo)記
? boolean?markSupported():測(cè)試當(dāng)前流是否支持mark和reset方法。如果支持,返回true,否則返回false
??void reset():此流的記錄指針重新定位到上一次記錄標(biāo)記(mark)的位置
??long skip(long n):在輸入流中跳過n個(gè)字節(jié),并返回實(shí)際跳過的字節(jié)數(shù)
3.輸出字節(jié)流OutputStream
1) OutputStream是所有的輸出字節(jié)流的抽象父類
2)ByteArrayOutputStream、FileOutputStream是兩種基本介質(zhì)流分別向Byte數(shù)組、和本地文件中寫入數(shù)據(jù)
3)ObjectOutputStream和所有FilterOutputStream的子類都是裝飾流
outputStream包含三個(gè)基本寫方法
??abstract void write(int b):將指定的字節(jié)輸出到輸出流中
??void write(byte[] b)?:將字節(jié)數(shù)組中的數(shù)據(jù)輸出到指定輸出流中
??void write(byte[] b, int off, int len)?:將字節(jié)數(shù)組數(shù)組中從off位置開始,長(zhǎng)度為len的字節(jié)輸出到輸出流中。
4.輸出字符流Writer
1)?Writer是所有的輸出字符流的抽象父類
2)CharArrayWriter、StringWriter是兩種基本的介質(zhì)流,它們分別向Char數(shù)組、String中寫入數(shù)據(jù)
3)PipedWriter是向與其它線程共用的管道中寫入數(shù)據(jù),
4)PrintWriter和PrintStream極其類似,功能和使用也非常相似
5)OutputStreamWriter是Writer的子類,將輸出的字符流變?yōu)樽止?jié)流,即將一個(gè)字符流的輸出對(duì)象變?yōu)樽止?jié)流的輸出對(duì)象
主要方法
? void write(int c):將指定的字符輸出到輸出流中
??void?write(byte[]/char[] buf):將字符數(shù)組中的數(shù)據(jù)輸出到指定輸出流中
??void write(byte[]/char[] buf, int off,int len ):將字符數(shù)組中從off位置開始,長(zhǎng)度為len的字符輸出到輸出流中
因?yàn)樽址髦苯右宰址鳛椴僮鲉挝?,所以Writer可以直接用String作為參數(shù)
??void write(String str):將str字符串里包含的字符輸出到指定輸出流中
??void write (String str, int off, int len):將str字符串里面從off位置開始,長(zhǎng)度為len的字符輸出到指定輸出流中
NIO
????????使用InputStream從輸入流中讀取數(shù)據(jù)時(shí),如果沒有讀取到有效數(shù)據(jù),程序?qū)⒃诖颂幾枞摼€程。其實(shí)傳統(tǒng)的輸入流和輸出流都是阻塞式的進(jìn)行輸入輸出,不僅如此,傳統(tǒng)的輸入流、輸出流都是通過字節(jié)的移動(dòng)處理的,一次只能處理一個(gè)字節(jié),效率不高
? ? ? ? 從JDK1.4開始,Java提供流一系列改進(jìn)的輸入和輸出處理的新功能,這些功能被統(tǒng)稱為新IO(NIO)。新增了許多用于處理輸入和輸出的類,這些類都被放在java.nio包及其子包下,并且對(duì)原io的很多類都以NIO為基礎(chǔ)進(jìn)行了改寫,新增了滿足NIO的功能。
? ? ? ? NIO采用了內(nèi)存映射對(duì)象的方式來處理輸入和輸出,NIo將文件或者文件的一塊區(qū)域映射到內(nèi)存中,這樣就可以像訪問對(duì)象一樣來訪問文件來。通過這種方式來進(jìn)行輸入、輸出比傳統(tǒng)的輸入、輸出要快的多。
JDk1.4使用NIO改寫了傳統(tǒng)Io后,傳統(tǒng)Io的讀寫速度和NIO差不了太多。
RandomAccessFile類
? ? ? ? 該對(duì)象并不是流體系中的一員,其封裝了字節(jié)流,同時(shí)還封裝了一個(gè)緩沖區(qū)(字符數(shù)組),通過內(nèi)部的指針來操作字符數(shù)組中的數(shù)據(jù)。
特點(diǎn):
1.該對(duì)象只能操作文件,所以構(gòu)造函數(shù)接收兩種類型的參數(shù):a.字符串文件路徑;b.File文件路徑
2.該對(duì)象即可以對(duì)文件進(jìn)行讀操作,也能進(jìn)行寫操作,在進(jìn)行對(duì)象實(shí)例化時(shí)可指定操作模式(r,rw)
注意:該對(duì)象在實(shí)例化時(shí),如果要操作的文件不存在,會(huì)自動(dòng)創(chuàng)建;如果文件存在,寫數(shù)據(jù)未指定位置,會(huì)從頭開始寫,即覆蓋原有的內(nèi)容。?可以用于多線程下載或多個(gè)線程同時(shí)寫數(shù)據(jù)到文件。
結(jié)尾
這篇文章集百家之長(zhǎng),混亂中大體說明白了JavaIO流,打完收工