File類? ??
目錄與文件的一個(gè)統(tǒng)稱啥寇,用于操縱目錄與文件嘉冒,并不能讀取數(shù)據(jù)蛙奖,只能創(chuàng)文件不能創(chuàng)目錄
目的:防止因?yàn)閷ο蟮南Фa(chǎn)生的數(shù)據(jù)丟失
構(gòu)造方法
常量
因?yàn)椴僮飨到y(tǒng)的不同所以獲取獲取文件對象時(shí)我們采用File f=new File("d:"+File.separator);
普通方法
單元測試
IO流:(流用完一定要close)
重點(diǎn)字節(jié)流和字符緩沖流和打印流
4個(gè)父類都是抽象類
輸入輸出是針對程序來說的
輸入指的是將內(nèi)容從文件(硬盤)中輸入到程序惫撰,(通過system.out方法將內(nèi)存讀到控制臺)亮垫,讀到程序中某個(gè)變量的內(nèi)存空間中
輸出流指的是從程序向文件(硬盤)中寫入數(shù)據(jù)模软,輸出流只要一創(chuàng)建,就默認(rèn)寫入一個(gè)空格
如果想向文件中寫入漢字饮潦,空格燃异,換行等只能使用字符流來實(shí)現(xiàn)
功能上分為:1.節(jié)點(diǎn)流 :直接插到數(shù)據(jù)源上? ? ? ?2.處理流:套在節(jié)點(diǎn)流上 :緩沖流、轉(zhuǎn)換流继蜡、數(shù)據(jù)流
FileInputStream(文件字節(jié)輸入流)
第一個(gè)read方法回俐,對于文件的讀取,相當(dāng)與指針指在了第一個(gè)位置稀并,每調(diào)用一次read方法指針就會(huì)移動(dòng)到下一個(gè)位置仅颇,當(dāng)讀取int值為-1的時(shí)候證明數(shù)據(jù)讀取完畢
第二個(gè)read方法,代表的不是一個(gè)數(shù)組碘举,而代表的是字節(jié)數(shù)組元素的個(gè)數(shù)忘瓦。把讀出的元素存入到一個(gè)byte數(shù)組里
注意:1.read()返回值是int型,所以輸出要轉(zhuǎn)換為char
? ? ? ? ? 2.流用完一定要close
FileOutputStream
1.覆蓋寫
FileOutputStream(String name)創(chuàng)建一個(gè)向具有指定名稱的文件中寫入數(shù)據(jù)的輸出文件流引颈。
2.追加寫
FileOutputStream(String name, boolean append)創(chuàng)建一個(gè)向具有指定name的文件中寫入數(shù)據(jù)的輸出文件流耕皮。
? ? ? ? ?假如一個(gè)文件中有很多內(nèi)容,想要把它輸入到另一個(gè)文件中蝙场,這時(shí)程序其實(shí)只運(yùn)行了一次凌停,所以不會(huì)產(chǎn)生覆蓋,也就是說當(dāng)復(fù)制一個(gè)圖片的時(shí)候售滤,雖然一個(gè)圖片的字節(jié)有很多罚拟,但是這些字節(jié)都是在程序一次運(yùn)行內(nèi)復(fù)制到另一個(gè)文件中的,所以不會(huì)產(chǎn)生覆蓋
Append:如果值為false代表的是從頭插入數(shù)據(jù),如果為true則代表的是程序再次運(yùn)行從尾部插入數(shù)據(jù)
注意:對于輸出流向一個(gè)文件中寫入數(shù)據(jù)的時(shí)候如果沒有該文件則會(huì)自動(dòng)創(chuàng)建一個(gè)文件舟舒,但是不能創(chuàng)建文件夾拉庶,每讀取一個(gè)字節(jié)都會(huì)存放在byte類型數(shù)組當(dāng)中,當(dāng)數(shù)組滿了之后會(huì)一次性的讀取出來秃励,所以這個(gè)數(shù)組在這里起到了一個(gè)緩沖的作用氏仗,目的是提高效率。
off-數(shù)據(jù)中的起始偏移量夺鲜,len-要寫入的字節(jié)數(shù)皆尔。
如何寫入字符串? ? ? 字符串有一個(gè)方法 ?getBytes()可以把字符串轉(zhuǎn)換為字節(jié)币励,然后存到字節(jié)數(shù)組然后寫入
字符流
特點(diǎn):每次操作的是一個(gè)字符
1.字符輸入流Reader :能讀取字符數(shù)組了慷蠕! ? 字符流讀到結(jié)尾等于null ,也就證明數(shù)據(jù)讀取完畢
文件字符輸入流FileReader
方法類似
2字符輸出流Writer:能輸入字符數(shù)組了食呻! ?
文件字符輸出流FileWriter
特有方法
FileInputStream in =new FileInputStream(“path”);
將一根管道插入文件準(zhǔn)備操作流炕,path是字符串(雙引號!)
例題:1.讀一文件字節(jié)()仅胞,將讀出的字節(jié)寫入到另一文件
2.讀文件每辟,將讀出來的字節(jié)存到一個(gè)字節(jié)數(shù)組中,然后將數(shù)組中的字節(jié)寫入到文件中
注:針對節(jié)點(diǎn)流干旧,文件讀到末尾都是等于 -1
對于字節(jié)流與字符流的使用場景
1字節(jié)流一般讀寫的都是.jpg.exe .zip這樣單位是字節(jié)的文件
2字符流一般讀寫的都是文本文件.txt .doc.ppt以字符為單位的文件
緩沖流
其實(shí)內(nèi)部也是封裝了字節(jié)數(shù)組渠欺。沒有指定緩沖區(qū)大小,默認(rèn)的字節(jié)是8192
緩沖流好處:沒有緩沖區(qū)就像逛超市沒有推車一樣椎眯,一次只能拿一樣?xùn)|西挠将,緩沖卻可以讓你把東西裝滿后再去結(jié)賬
BufferedReader BufferedWriter BufferedInputStream? BufferedOutputStream
提高效率,減少讀寫次數(shù)编整,當(dāng)緩沖區(qū)數(shù)據(jù)充滿的時(shí)候會(huì)自動(dòng)的把數(shù)據(jù)一些性寫入或者讀出舔稀,保護(hù)硬盤,套在節(jié)點(diǎn)流上掌测,參數(shù)是節(jié)點(diǎn)流
FileWriter fw=new FileWriter(“path”)
BufferedWriter bufw=new BufferedWriter(fw)镶蹋;
方法(字符流)
newLine()寫入一個(gè)空行
readLine()讀一行
flush()
因?yàn)橛幸恍㊣O流用的是緩沖方式:它有個(gè)緩沖區(qū),一般得等到緩沖區(qū)滿才寫入文件赏半。動(dòng)態(tài)調(diào)用flush則不管緩沖區(qū)滿不滿,立即寫到文件淆两。如果最后緩沖區(qū)沒滿而關(guān)閉流断箫,則會(huì)導(dǎo)致數(shù)據(jù)丟失。其實(shí)大多數(shù)流的close()方法都自動(dòng)調(diào)用了flush方法
當(dāng)讀入的文件到結(jié)尾readLine=null
轉(zhuǎn)換流
從字節(jié)流----》轉(zhuǎn)換為字符流
InputStreamReader輸入轉(zhuǎn)換流字符流處理流
OutputStreamWriter輸出轉(zhuǎn)換流字符流處理流
它們有轉(zhuǎn)換作用秋冰,而本身又是字符流仲义。所以在構(gòu)造方法內(nèi)的參數(shù)是字節(jié)流
控制臺輸入:
BufferedRead br=new BufferedRead(new InputStreamReader(System.in))
數(shù)據(jù)流
可以把基本類型直接寫入文件和從文件中讀出(專門用網(wǎng)絡(luò)間的數(shù)據(jù)傳遞)
DataInputStream
DataOutputStream。
對象流
將一個(gè)對象整體輸入到文件中
序列化:把對象存入到文件中
1.將節(jié)點(diǎn)流插到文件上,將處理流套到節(jié)點(diǎn)流上
FileOutputStream fileStream=new FileOutputStream("path");
ObjectOutputStream os=new ObjectOutputStream(fileStream);
2.寫入對象
os.writeObject( );
3.關(guān)閉流
os.close()? ? 關(guān)閉流的時(shí)候只關(guān)閉處理流就可以了
對象被序列化的過程究竟都發(fā)生了什么埃撵?
(1)在堆上創(chuàng)建對象
(2)對象被碾平也就是被序列化赵颅,進(jìn)入到了對象流中
(3)經(jīng)過字節(jié)流,值被抽出到流上和虛擬機(jī)所需要的信息一起被保存到文件中
當(dāng)一個(gè)對象的實(shí)例變量是引用的時(shí)候暂刘,會(huì)自動(dòng)將其引用也進(jìn)行序列化饺谬,類似集合被序列化的時(shí)候,集合所包含的對象也會(huì)被序列化
如何實(shí)現(xiàn)序列化
? ? ? ?實(shí)現(xiàn)Serializable,這個(gè)接口是一個(gè)標(biāo)記接口谣拣,因?yàn)槠渲袥]有任何方法要實(shí)現(xiàn)募寨,唯一目的是說明此類是可以被序列化的,若父類是可被序列化森缠,那么它的子類也是可以被序列化的拔鹰。如果想要哪個(gè)實(shí)例變量不能被序列化,那么就用transient修飾贵涵,靜態(tài)變量也不會(huì)被初值化(或者實(shí)現(xiàn)externaliable是serializable的一個(gè)子接口列肢,可以控制序列化的過程,而serializable是虛擬機(jī)自動(dòng)控制了)
反序列化:把對象從文件中獲取出來
1.將節(jié)點(diǎn)流插到文件上宾茂,將處理流套到節(jié)點(diǎn)流上
FileInputStream fileStream=new FileInputStream("path");
ObjectInputStream os=new ObjectInputStream(fileStream);
2.讀取對象
Object one=os.readObject() ??
3.轉(zhuǎn)換對象類型
Game g=(Game)one
4.關(guān)閉流
os.close()
在解序列化的過程中瓷马,所有類都必須能讓Java虛擬機(jī)找到,就是類要寫上
private static final long serialVersionUID = 1L;
對象序列化的時(shí)候所遇到的問題:
InvalidClassException
該類的序列版本號與從流中讀取的類描述符的版本號不匹配刻炒,該類包含未知數(shù)據(jù)類型决采,該類沒有可訪問的無參數(shù)構(gòu)造方法(類中未定義版本號)
EOFException
該異常針對于對象流,其它流的讀到文件的末尾一般返回的是-1或者是null對象特殊返回的是一個(gè)異常
內(nèi)存流(了解)
ByteArrayInputStream ? 寫出
ByteArrayOutputStream ? ?寫入
ByteArrayInputStream主要完成將內(nèi)容從內(nèi)存讀入程序之中坟奥,而ByteArrayOutputStream的功能主要是將數(shù)據(jù)寫入到內(nèi)存中树瞭。(與常規(guī)的輸入輸出流正好相反)。
我們從網(wǎng)上下載的資源例如音樂小文本一些小的文件不適合直接存儲(chǔ)到本地磁盤當(dāng)中爱谁,需要進(jìn)行處理晒喷,這個(gè)時(shí)候會(huì)把這些數(shù)據(jù)存入到內(nèi)存當(dāng)中,內(nèi)存流的本質(zhì)其實(shí)就是一個(gè)動(dòng)態(tài)數(shù)組
注:輸入輸出是針對程序來說的
字節(jié)數(shù)組中先寫進(jìn)什么访敌,就要先輸出什么凉敲,先進(jìn)先出類似隊(duì)列
打印流(了解)
PrintStream字節(jié)打印流
它的構(gòu)造函數(shù)可以接收三種數(shù)據(jù)類型的值。
1寺旺,字符串路徑爷抓。
2,F(xiàn)ile對象阻塑。
3蓝撇,OutputStream。
print方法和write方法的區(qū)別在于,print提供自動(dòng)刷新.
普通的write方法需要調(diào)用flush或者close方法才可以看到數(shù)據(jù).
網(wǎng)絡(luò)間傳輸要換行和flush不然無法讀取
PrintWriter字符打印流
是一個(gè)字符打印流陈莽。構(gòu)造函數(shù)可以接收四種類型的值渤昌。
1虽抄,字符串路徑恤批。
2镜沽,F(xiàn)ile對象。
對于1挎塌,2類型的數(shù)據(jù)忌栅,還可以指定編碼表车酣。也就是字符集。
3狂秘,OutputStream
4骇径,Writer
FileWriter fw = new FileWriter("C:\\log.txt", true);
PrintWriter log = new PrintWriter(fw,true);
注意:PrintWriter的構(gòu)造方法的第二個(gè)參數(shù),只有true才會(huì)自動(dòng)flush者春。
可以向文件中打印各種數(shù)據(jù)包括基本數(shù)據(jù)和引用類型
序列流破衔,合并流
SequenceInputStream表示其他輸入流的邏輯串聯(lián)。它從輸入流的有序集合開始钱烟,并從第一個(gè)輸入流開始讀取晰筛,直到到達(dá)文件末尾,接著從第二個(gè)輸入流讀取拴袭,依次類推读第,直到到達(dá)包含的最后一個(gè)輸入流的文件末尾為止。