java IO流學(xué)習(xí)總結(jié)
近期學(xué)習(xí)了Java的IO流,嘗試著總結(jié)一下笑诅。
java.io 包下的IO流很多:
其中端朵,以Stream結(jié)尾的為字節(jié)流,以Writer或者Reader結(jié)尾的為字符流挟炬。所有的輸入流都是抽象類IuputStream(字節(jié)輸入流)或者抽象類Reader(字符輸入流)的子類,所有的輸出流都是抽象類OutputStream(字節(jié)輸出流)或者抽象類Writer(字符輸出流)的子類嗦哆。字符流能實(shí)現(xiàn)的功能字節(jié)流都能實(shí)現(xiàn)谤祖,反之不一定。如:圖片老速,視頻等二進(jìn)制文件粥喜,只能使用字節(jié)流讀寫。
1橘券、字符流FileReader和FileWriter
FileReader類
構(gòu)造方法摘要
FileReader(Filefile)
在給定從中讀取數(shù)據(jù)的File的情況下創(chuàng)建一個(gè)新FileReader额湘。
在給定從中讀取數(shù)據(jù)的FileDescriptor的情況下創(chuàng)建一個(gè)新FileReader卿吐。
FileReader(StringfileName)
在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新FileReader。
?FileWriter類
構(gòu)造方法摘要
FileWriter(Filefile)
根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象锋华。
FileWriter(Filefile, boolean?append)
根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象嗡官。
構(gòu)造與某個(gè)文件描述符相關(guān)聯(lián)的 FileWriter 對(duì)象。
FileWriter(StringfileName)
根據(jù)給定的文件名構(gòu)造一個(gè) FileWriter 對(duì)象供置。
FileWriter(StringfileName, boolean?append)
根據(jù)給定的文件名以及指示是否附加寫入數(shù)據(jù)的 boolean 值來(lái)構(gòu)造 FileWriter 對(duì)象谨湘。
使用FileReader和FileWriter類完成文本文件復(fù)制:
CopyFile
2、字符緩沖流BufferedReader和BufferedWriter
字符緩沖流具備文本特有的表現(xiàn)形式芥丧,行操作
public classBufferedReader?extendsReader
(1)從字符輸入流中讀取文本,緩沖各個(gè)字符坊罢,從而實(shí)現(xiàn)字符续担、數(shù)組和行的高效讀取。
(2)可以指定緩沖區(qū)的大小活孩,或者可使用默認(rèn)的大小物遇。大多數(shù)情況下,默認(rèn)值就足夠大了憾儒。
(3)通常询兴,Reader
所作的每個(gè)讀取請(qǐng)求都會(huì)導(dǎo)致對(duì)底層字符或字節(jié)流進(jìn)行相應(yīng)的讀取請(qǐng)求。因此起趾,建議用 BufferedReader 包裝所有其 read()
操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)诗舰。例如,
BufferedReader in
? = new BufferedReader(new FileReader("foo.in"));
(4)將緩沖指定文件的輸入训裆。如果沒有緩沖眶根,則每次調(diào)用 read() 或readLine()都會(huì)導(dǎo)致從文件中讀取字節(jié),并將其轉(zhuǎn)換為字符后返回边琉,而這是極其低效的属百。
public classBufferedWriter?extendsWriter
(1)將文本寫入字符輸出流,緩沖各個(gè)字符变姨,從而提供單個(gè)字符族扰、數(shù)組和字符串的高效寫入。
(2)可以指定緩沖區(qū)的大小定欧,或者接受默認(rèn)的大小渔呵。在大多數(shù)情況下,默認(rèn)值就足夠大了忧额。
(3)該類提供了newLine() 方法厘肮,它使用平臺(tái)自己的行分隔符概念,此概念由系統(tǒng)屬性line.separator定義睦番。并非所有平臺(tái)都使用新行符 ('\n') 來(lái)終止各行类茂。因此調(diào)用此方法來(lái)終止每個(gè)輸出行要優(yōu)于直接寫入新行符掰伸。
(4)通常 Writer
將其輸出立即發(fā)送到底層字符或字節(jié)流。除非要求提示輸出崖面,否則建議用 BufferedWriter 包裝所有其 write() 操作可能開銷很高的
Writer(如 FileWriters 和 OutputStreamWriters)椅寺。例如,
PrintWriter out? = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
(5)緩沖 PrintWriter 對(duì)文件的輸出兢哭。如果沒有緩沖领舰,則每次調(diào)用 print() 方法會(huì)導(dǎo)致將字符轉(zhuǎn)換為字節(jié),然后立即寫入到文件迟螺,而這是極其低效的冲秽。
?使用BufferedReader和BufferedWriter完成文件復(fù)制
CopyFile2
緩沖區(qū)的工作原理:1、使用了底層流對(duì)象從具體設(shè)備上獲取數(shù)據(jù)矩父,并將數(shù)據(jù)存儲(chǔ)到緩沖區(qū)的數(shù)組內(nèi)锉桑。2、通過(guò)緩沖區(qū)的read()方法從緩沖區(qū)獲取具體的字符數(shù)據(jù)窍株,這樣就提高了效率民轴。3、如果用read方法讀取字符數(shù)據(jù)球订,并存儲(chǔ)到另一個(gè)容器中后裸,直到讀取到了換行符時(shí),將另一個(gè)容器臨時(shí)存儲(chǔ)的數(shù)據(jù)轉(zhuǎn)成字符串返回冒滩,就形成了readLine()功能微驶。
3、字節(jié)流FileInputStream和FileOutputStream?
public classFileInputStream?extendsInputStream
(1)FileInputStream從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)旦部。哪些文件可用取決于主機(jī)環(huán)境祈搜。
(2)FileInputStream用于讀取諸如圖像數(shù)據(jù)之類的原始字節(jié)流。
構(gòu)造方法摘要
FileInputStream(Filefile)
通過(guò)打開一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè)FileInputStream士八,該文件通過(guò)文件系統(tǒng)中的File對(duì)象file指定容燕。
FileInputStream(FileDescriptorfdObj)
通過(guò)使用文件描述符fdObj創(chuàng)建一個(gè)FileInputStream,該文件描述符表示到文件系統(tǒng)中某個(gè)實(shí)際文件的現(xiàn)有連接婚度。
FileInputStream(Stringname)
通過(guò)打開一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè)FileInputStream蘸秘,該文件通過(guò)文件系統(tǒng)中的路徑名name指定。
public classFileOutputStream?extendsOutputStream
(1)文件輸出流是用于將數(shù)據(jù)寫入File或FileDescriptor的輸出流蝗茁。文件是否可用或能否可以被創(chuàng)建取決于基礎(chǔ)平臺(tái)醋虏。特別是某些平臺(tái)一次只允許一個(gè)FileOutputStream(或其他文件寫入對(duì)象)打開文件進(jìn)行寫入。在這種情況下哮翘,如果所涉及的文件已經(jīng)打開颈嚼,則此類中的構(gòu)造方法將失敗。(2)FileOutputStream用于寫入諸如圖像數(shù)據(jù)之類的原始字節(jié)的流饭寺。
構(gòu)造方法摘要
FileOutputStream(Filefile)
創(chuàng)建一個(gè)向指定File對(duì)象表示的文件中寫入數(shù)據(jù)的文件輸出流阻课。
FileOutputStream(Filefile, boolean?append)
創(chuàng)建一個(gè)向指定File對(duì)象表示的文件中寫入數(shù)據(jù)的文件輸出流叫挟。
FileOutputStream(FileDescriptorfdObj)
創(chuàng)建一個(gè)向指定文件描述符處寫入數(shù)據(jù)的輸出文件流,該文件描述符表示一個(gè)到文件系統(tǒng)中的某個(gè)實(shí)際文件的現(xiàn)有連接限煞。
FileOutputStream(Stringname)
創(chuàng)建一個(gè)向具有指定名稱的文件中寫入數(shù)據(jù)的輸出文件流抹恳。
FileOutputStream(Stringname, boolean?append)
創(chuàng)建一個(gè)向具有指定name的文件中寫入數(shù)據(jù)的輸出文件流。
例:使用字節(jié)流復(fù)制圖片
1import java.io.FileInputStream; 2import java.io.FileOutputStream; 3import java.io.IOException; 4 5publicclass CopImg { 6publicstaticvoidmain(String[] args)throws IOException { 7FileInputStream fin=newFileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg"); 8FileOutputStream fout=newFileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopy.jpg"); 9intlen=0;10byte[] buff=newbyte[1024];11while((len=fin.read(buff))!=-1) {12fout.write(buff, 0, len);13? ? ? ? }14? ? ? ? fin.close();15? ? ? ? fout.close();16? ? }17}
4署驻、字節(jié)緩沖流BufferedInputStream和BufferedOutputStream
public classBufferedInputStream?extendsFilterInputStream
BufferedInputStream為另一個(gè)輸入流添加一些功能奋献,即緩沖輸入以及支持mark和reset方法的能力。在創(chuàng)建BufferedInputStream時(shí)旺上,會(huì)創(chuàng)建一個(gè)內(nèi)部緩沖區(qū)數(shù)組瓶蚂。在讀取或跳過(guò)流中的字節(jié)時(shí),可根據(jù)需要從包含的輸入流再次填充該內(nèi)部緩沖區(qū)抚官,一次填充多個(gè)字節(jié)扬跋。mark操作記錄輸入流中的某個(gè)點(diǎn),reset操作使得在從包含的輸入流中獲取新字節(jié)之前凌节,再次讀取自最后一次mark操作后讀取的所有字節(jié)。
public classBufferedOutputStream?extendsFilterOutputStream
該類實(shí)現(xiàn)緩沖的輸出流洒试。通過(guò)設(shè)置這種輸出流倍奢,應(yīng)用程序就可以將各個(gè)字節(jié)寫入底層輸出流中,而不必針對(duì)每次字節(jié)寫入調(diào)用底層系統(tǒng)垒棋。
例:使用字節(jié)緩沖流實(shí)現(xiàn)圖片的復(fù)制
1import java.io.BufferedInputStream; 2import java.io.BufferedOutputStream; 3import java.io.FileInputStream; 4import java.io.FileOutputStream; 5import java.io.IOException; 6 7publicclass CopyImg { 8publicstaticvoidmain(String[] args)throws IOException { 9BufferedInputStream bfin=newBufferedInputStream(newFileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg"));10BufferedOutputStream bfout=newBufferedOutputStream(newFileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopybuff.jpg"));11intlen=0;12byte[] buff=newbyte[1024];13while((len=bfin.read(buff))!=-1) {14bfout.write(buff, 0, len);15? ? ? ? }16? ? ? ? bfin.close();17? ? ? ? bfout.close();18? ? }19}
5卒煞、轉(zhuǎn)換流:InputStreamReader和OutputStreamWriter
InputStreamReader和OutputStreamWriter是字符和字節(jié)的橋梁,也可稱之為字符轉(zhuǎn)換流叼架。原理:字節(jié)流+編碼畔裕。
FileReader和FileWriter作為子類,僅作為操作字符文件的便捷類存在乖订。當(dāng)操作的字符文件扮饶,使用的是默認(rèn)編碼表時(shí)可以不用父類,而直接使用子類完成操作乍构,簡(jiǎn)化代碼甜无。
一旦要指定其他編碼時(shí),不能使用子類哥遮,必須使用字符轉(zhuǎn)換流岂丘。
public classInputStreamReader?extendsReader
(1)InputStreamReader 是字節(jié)流通向字符流的橋梁:它使用指定的charset讀取字節(jié)并將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定眠饮,或者可以接受平臺(tái)默認(rèn)的字符集奥帘。
(2)每次調(diào)用 InputStreamReader 中的一個(gè) read() 方法都會(huì)導(dǎo)致從底層輸入流讀取一個(gè)或多個(gè)字節(jié)。要啟用從字節(jié)到字符的有效轉(zhuǎn)換仪召,可以提前從底層流讀取更多的字節(jié)寨蹋,使其超過(guò)滿足當(dāng)前讀取操作所需的字節(jié)松蒜。
(3)為了達(dá)到最高效率,可以考慮在 BufferedReader 內(nèi)包裝 InputStreamReader钥庇。例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in))牍鞠;//重要
InputStreamReaderDemo
public classOutputStreamWriter?extendsWriter
(1)OutputStreamWriter 是字符流通向字節(jié)流的橋梁:可使用指定的charset將要寫入流中的字符編碼成字節(jié)。它使用的字符集可以由名稱指定或顯式給定评姨,否則將接受平臺(tái)默認(rèn)的字符集难述。
(2)每次調(diào)用 write() 方法都會(huì)導(dǎo)致在給定字符(或字符集)上調(diào)用編碼轉(zhuǎn)換器。在寫入底層輸出流之前吐句,得到的這些字節(jié)將在緩沖區(qū)中累積胁后。可以指定此緩沖區(qū)的大小嗦枢,不過(guò)攀芯,默認(rèn)的緩沖區(qū)對(duì)多數(shù)用途來(lái)說(shuō)已足夠大。注意文虏,傳遞給 write() 方法的字符沒有緩沖侣诺。
(3)為了獲得最高效率,可考慮將 OutputStreamWriter 包裝到 BufferedWriter 中氧秘,以避免頻繁調(diào)用轉(zhuǎn)換器年鸳。例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));//重要
例如:利用標(biāo)準(zhǔn)輸出流將文本輸出到命令行
OutputStreamWriterDemo
TransStreamDemo
6、打印流PrintWriter和PrintStream
public classPrintWriter?extendsWriter
(1)向文本輸出流打印對(duì)象的格式化表示形式丸相。此類實(shí)現(xiàn)在PrintStream中的所有print方法搔确。不能輸出字節(jié),但是可以輸出其他任意類型灭忠。
(2)與PrintStream類不同膳算,如果啟用了自動(dòng)刷新,則只有在調(diào)用println弛作、printf或format的其中一個(gè)方法時(shí)才可能完成此操作涕蜂,而不是每當(dāng)正好輸出換行符時(shí)才完成。這些方法使用平臺(tái)自有的行分隔符概念缆蝉,而不是換行符宇葱。
(3)此類中的方法不會(huì)拋出 I/O 異常,盡管其某些構(gòu)造方法可能拋出異常刊头∈蚯疲客戶端可能會(huì)查詢調(diào)用checkError()是否出現(xiàn)錯(cuò)誤。
1import java.io.FileWriter; 2import java.io.IOException; 3import java.io.PrintWriter; 4/** 5 * 注意:創(chuàng)建FileWriter對(duì)象時(shí)boolean參數(shù)表示是否追加原杂; 6 *? ? ? ? ? ? ? 而創(chuàng)建打印流對(duì)象時(shí)boolean參數(shù)表示是否自動(dòng)刷新 7*/ 8publicclass PrintWriterDemo { 9publicstaticvoidmain(String[] args)throws IOException {10//PrintWriter pw=new PrintWriter("print.txt");11PrintWriter pw=newPrintWriter(newFileWriter("print.txt"),true);12pw.write("測(cè)試打印流");13pw.println("此句之后換行");14pw.println("特有功能:自動(dòng)換行和自動(dòng)刷新");15pw.println("利用構(gòu)造器設(shè)置自動(dòng)刷新");16? ? ? ? pw.close();17? ? }18}
使用字符打印流復(fù)制文本文件:
PrintWriterDemo
publicclass PrintStream extendsFilterOutputStreamimplementsAppendable,Closeable(1)PrintStream為其他輸出流添加了功能(增加了很多打印方法)印颤,使它們能夠方便地打印各種數(shù)據(jù)值表示形式(例如:希望寫一個(gè)整數(shù),到目的地整數(shù)的表現(xiàn)形式不變穿肄。字節(jié)流的write方法只將一個(gè)整數(shù)的最低字節(jié)寫入到目的地年局,比如寫fos.write(97)际看,到目的地(記事本打開文件)會(huì)變成字符'a',需要手動(dòng)轉(zhuǎn)換:fos.write(Integer.toString(97).getBytes());而采用PrintStream:ps.print(97),則可以保證數(shù)據(jù)的表現(xiàn)形式)矢否。
1//PrintStream的print方法 2publicvoidprint(int i) {3? ? ? ? write(String.valueOf(i));4}
(2)與其他輸出流不同仲闽,PrintStream永遠(yuǎn)不會(huì)拋出IOException;而是僵朗,異常情況僅設(shè)置可通過(guò)checkError方法測(cè)試的內(nèi)部標(biāo)志赖欣。
另外,為了自動(dòng)刷新验庙,可以創(chuàng)建一個(gè)PrintStream顶吮;這意味著可在寫入 byte 數(shù)組之后自動(dòng)調(diào)用flush方法,可調(diào)用其中一個(gè)println方法粪薛,或?qū)懭胍粋€(gè)換行符或字節(jié) ('\n')悴了。
(3)PrintStream打印的所有字符都使用平臺(tái)的默認(rèn)字符編碼轉(zhuǎn)換為字節(jié)。在需要寫入字符而不是寫入字節(jié)的情況下违寿,應(yīng)該使用PrintWriter類湃交。
使用字節(jié)打印流復(fù)制文本文件:
PrintStreamDemo
7、對(duì)象操作流ObjectInputStream和ObjectOutputStream
public classObjectOutputStream?extendsOutputStream?implementsObjectOutput,ObjectStreamConstants
(1)ObjectOutputStream 將 Java 對(duì)象的基本數(shù)據(jù)類型和圖形寫入 OutputStream藤巢。只能使用 ObjectInputStream 讀妊沧帷(重構(gòu))對(duì)象。
(2)只能將支持 java.io.Serializable 接口的對(duì)象寫入流中菌瘪。
(3)writeObject 方法用于將對(duì)象寫入流中。所有對(duì)象(包括 String 和數(shù)組)都可以通過(guò) writeObject 寫入阱当∏卫可將多個(gè)對(duì)象或基元寫入流中。必須使用與寫入對(duì)象時(shí)相同的類型和順序從相應(yīng) ObjectInputstream 中讀回對(duì)象弊添。
構(gòu)造方法:ObjectOutputStream(OutputStreamout)創(chuàng)建寫入指定 OutputStream 的 ObjectOutputStream录淡。
public classObjectInputStream?extendsInputStream?implementsObjectInput,ObjectStreamConstants
(1)ObjectInputStream 對(duì)以前使用 ObjectOutputStream 寫入的基本數(shù)據(jù)和對(duì)象進(jìn)行反序列化。
(2)只有支持 java.io.Serializable 或 java.io.Externalizable 接口的對(duì)象才能從流讀取油坝。
(3)readObject方法用于從流讀取對(duì)象嫉戚。應(yīng)該使用 Java 的安全強(qiáng)制轉(zhuǎn)換來(lái)獲取所需的類型。在 Java 中澈圈,字符串和數(shù)組都是對(duì)象彬檀,所以在序列化期間將其視為對(duì)象。讀取時(shí)瞬女,需要將其強(qiáng)制轉(zhuǎn)換為期望的類型窍帝。
例:對(duì)象讀寫:
Student
ObjectOperate
ObjectOperate2
序列化接口Serializable的作用:沒有方法,不需要覆寫诽偷,是一個(gè)標(biāo)記接口為了啟動(dòng)一個(gè)序列化功能坤学。唯一的作用就是給每一個(gè)需要序列化的類都分配一個(gè)序列版本號(hào)疯坤,這個(gè)版本號(hào)和類相關(guān)聯(lián)。在序列化時(shí)深浮,會(huì)將這個(gè)序列號(hào)也一同保存在文件中压怠,在反序列化時(shí)會(huì)讀取這個(gè)序列號(hào)和本類的序列號(hào)進(jìn)行匹配,如果不匹配會(huì)拋出java.io.InvalidClassException.
注意:靜態(tài)數(shù)據(jù)不會(huì)被序列化飞苇,因?yàn)殪o態(tài)數(shù)據(jù)在方法區(qū)菌瘫,不在對(duì)象里。
或者使用transient關(guān)鍵字修飾玄柠,也不會(huì)序列化突梦。
8、SequenceInputStream?
表示其他輸入流的邏輯串聯(lián)羽利。它從輸入流的有序集合開始宫患,并從第一個(gè)輸入流開始讀取,直到到達(dá)文件末尾这弧,接著從第二個(gè)輸入流讀取娃闲,依次類推,直到到達(dá)包含的最后一個(gè)輸入流的文件末尾為止匾浪。
案例:媒體文件切割與合并
CutFile
mergeFile
9皇帮、用于操作數(shù)組和字符串的流對(duì)象
ByteArrayInputStream? ByteArrayOutputStream
CharArrayReader? CharArrayWriter
StringReader StringWriter
關(guān)閉這些流都是無(wú)效的,因?yàn)檫@些都未調(diào)用系統(tǒng)資源蛋辈,不需要拋IO異常属拾。
View Code
10、RandomAccessFile
View Code
11冷溶、File類:
File: 文件和目錄路徑名的抽象表示形式渐白,F(xiàn)ile類的實(shí)例是不可改變的
(1)File類常用功能
File:文件和目錄路徑名的抽象表示形式,F(xiàn)ile類的實(shí)例是不可改變的* File類的構(gòu)造方法:
*? ? ? ? ? ? File(String pathname) 將指定的路徑名轉(zhuǎn)換成一個(gè)File對(duì)象
*? ? ? ? ? ? File(String parent,String child) 根據(jù)指定的父路徑和文件路徑創(chuàng)建對(duì)象
*? ? ? ? ? ? File(File parent,String child)
* File類常用功能:
*? ? ? ? ? ? 創(chuàng)建:booleancreateNewFile():當(dāng)指定文件(或文件夾)不存在時(shí)創(chuàng)建文件并返回true逞频,否則返回false纯衍,路徑不存在則拋出異常*booleanmkdir()? :當(dāng)指定文件(或文件夾)不存在時(shí)創(chuàng)建文件夾并返回true,否則返回false*booleanmkdirs() :創(chuàng)建指定文件夾苗胀,所在文件夾目錄不存在時(shí)襟诸,則順道一塊創(chuàng)建
*? ? ? ? ? ? 刪除:boolean delete():刪除文件
注意:要?jiǎng)h除一個(gè)目錄,需要先刪除這個(gè)目錄下的所有子文件和子目錄
*? ? ? ? ? ? 獲然:File getAbsoluteFile()
*? ? ? ? ? ? ? ? File getParentFile()
*? ? ? ? ? ? ? ? String getAbsolutePath()
*? ? ? ? ? ? ? ? String getParent()
*? ? ? ? ? ? ? ? String getPath()
*long lastModified()
*? ? ? ? ? ? 判斷:boolean exists();
*boolean isAbsolute()
*boolean isDirectory()
*boolean isFile()
*boolean isHidden()? ?
*? ? ? ? ? ? 修改:booleanrenameTo(File dest): 將當(dāng)前File對(duì)象所指向的路徑修改為指定File所指的路徑 (修改文件名稱)
案例:打印指定文件(夾)及其所有子目錄
1import java.io.File; 2/** 3 *打印目錄 4*/ 5publicclass FileDemo1 { 6publicstaticvoid main(String[] args){ 7File f=newFile("E:\\BaiduNetdiskDownload"); 8printTree( f,0); 9? ? }1011publicstaticvoidprintTree(File f,int level) {12for(intj=0;j
?(2)File類重要方法之過(guò)濾器
String[] list()
String[] list(FilenameFilter)
File[] listFiles()
File[] listFiles(FilenameFilter)
File[] listFiles(FileFilter filter)
File類的list方法可以獲取目錄下的各個(gè)文件歌亲,傳入過(guò)濾器還能按照特定需求取出需要的文件。下面來(lái)看一下過(guò)濾器怎么用的堡掏。首先看
String[] list(FilenameFilter)
查看FilenameFilter源碼应结,發(fā)現(xiàn)其實(shí)是一個(gè)接口:
publicinterface FilenameFilter {
? ? /**? ? * Tests if a specified file should be included in a file list.
? ? *
? ? * @param? dir? ? the directory in which the file was found.
? ? * @param? name? the name of the file.
? ? * @return? <code>true</code> if and only if the name should be
? ? * included in the file list; <code>false</code> otherwise.
? ? */boolean accept(File dir, String name);
}
那么我們要想使用過(guò)濾器,應(yīng)該先實(shí)現(xiàn)接口,假設(shè)我們要找某個(gè)文件夾下的txt文件:
1import java.io.File; 2import java.io.FilenameFilter; 3 4publicclass FileDemo { 5publicstaticvoid main(String[] args) { 6File file =newFile("C:\\Test"); 7if(file.isDirectory()) { 8String[] list=file.list(new FilenameFilterbytxt());//傳入過(guò)濾器 9for(String l:list) {10? ? ? ? ? ? ? ? System.out.println(l);11? ? ? ? ? ? }12? ? ? ? }13? ? }14}1516classFilenameFilterbytxtimplements FilenameFilter{17? ? @Override18publicboolean accept(File dir, String name) {19// TODO Auto-generated method stub20returnname.endsWith(".txt");//當(dāng)文件名以.txt結(jié)尾時(shí)返回true.21? ? }2223}
但是我們看到第8行代碼只是傳入了過(guò)濾器鹅龄,那么accept方法是如何被調(diào)用的呢揩慕?查看
String[] list(FilenameFilter) 的源碼:
1? /*list(FilenameFilter)源碼解析*/ 2public String[] list(FilenameFilter filter) { 3String names[] = list();//調(diào)用list()方法獲取所有名稱 4if((names ==null) || (filter ==null)) { 5return names;? 6? ? ? ? } 7List v =newArrayList<>();//用于保存過(guò)濾后的文件名 8for(inti = 0 ; i < names.length ; i++) {//遍歷 9//調(diào)用filter的accept方法,傳入當(dāng)前目錄this和遍歷到的名稱names[i]10if(filter.accept(this, names[i])) {11v.add(names[i]);//滿足過(guò)濾器條件的添加到集合中12? ? ? ? ? ? }13? ? ? ? }14returnv.toArray(newString[v.size()]);//將集合轉(zhuǎn)成數(shù)組返回扮休,限定增刪操作15}
也就是說(shuō)迎卤,我們實(shí)現(xiàn)的accept方法是在構(gòu)造器中被調(diào)用的。
類似地玷坠,F(xiàn)ileFilter 也是一個(gè)接口蜗搔,采用匿名內(nèi)部類的方式實(shí)現(xiàn)接口,使用File[] listFiles(FileFilter filter)獲取目錄下所有文件夾:
1import java.io.File; 2import java.io.FileFilter; 3 4publicclass FileDemo { 5publicstaticvoid main(String[] args) { 6File file =newFile("C:\\Test"); 7if(file.isDirectory()) { 8File[] list=file.listFiles(new FileFilter() { 9? ? ? ? ? ? ? ? @Override10publicboolean accept(File pathname) {11// TODO Auto-generated method stub12returnpathname.isDirectory();13? ? ? ? ? ? ? ? }1415? ? ? ? ? ? });1617for(File f:list) {18? ? ? ? ? ? ? ? System.out.println(f);19? ? ? ? ? ? }20? ? ? ? }21? ? }22}
?File[] listFiles(FileFilter filter) 方法的源碼如下:
1/*File[] listFiles(FileFilter filter)源碼解析*/ 2public File[] listFiles(FileFilter filter) { 3String ss[] = list();//調(diào)用list()獲取所有的名稱數(shù)組 4if(ss ==null)returnnull;//健壯性判斷八堡,數(shù)組為null則返回 5ArrayList files =newArrayList<>();//創(chuàng)建File類型集合 6for(String s : ss) {//遍歷 7File f =newFile(s,this);//private File(String child, File parent)私有構(gòu)造調(diào)用 8if((filter ==null) || filter.accept(f))//條件判斷 9files.add(f);//添加到集合10? ? ? ? }11returnfiles.toArray(newFile[files.size()]);//集合轉(zhuǎn)成數(shù)組返回12}
?12樟凄、IO流使用規(guī)律總結(jié):
(1)明確要操作的數(shù)據(jù)是數(shù)據(jù)源還是數(shù)據(jù)目的(要讀還是要寫)
源:InputStream Reader
目的:OutputStream Writer
?(2)明確要操作的設(shè)備上的數(shù)據(jù)是字節(jié)還是文本
源:
字節(jié):InputStream
文本:Reader
目的:
字節(jié):OutputStream
文本:Writer
(3)明確數(shù)據(jù)所在的具體設(shè)備
源設(shè)備:
硬盤:文件 File開頭
內(nèi)存:數(shù)組,字符串
鍵盤:System.in
網(wǎng)絡(luò):Socket
目的設(shè)備:
硬盤:文件 File開頭
內(nèi)存:數(shù)組兄渺,字符串
屏幕:System.out
網(wǎng)絡(luò):Socket
(4)明確是否需要額外功能缝龄?
需要轉(zhuǎn)換——轉(zhuǎn)換流 InputStreamReader OutputStreamWriter
需要高效——緩沖流Bufferedxxx
多個(gè)源——序列流 SequenceInputStream
對(duì)象序列化——ObjectInputStream,ObjectOutputStream
保證數(shù)據(jù)的輸出形式——打印流PrintStream Printwriter
操作基本數(shù)據(jù),保證字節(jié)原樣性——DataOutputStream,DataInputStream