Java-进阶:Java-File--IO—2
目錄
一、轉(zhuǎn)換流
二、字節(jié)緩沖流
三、字符緩沖流
四、序列化流與反序列化流
五、打印流
六、標(biāo)準(zhǔn)輸入、輸出流
七、IO流總結(jié)
一、轉(zhuǎn)換流
1. OutputStreamWriter 類
(1) 概述
- java.io.OutputStreamWriter繼承 Writer類;就是一個(gè)字符輸出流,寫文本文件;
- 是字符通向字節(jié)的橋梁,將 字符流 轉(zhuǎn)成 字節(jié)流
- write():字符,字符數(shù)組,字符串
(2) 構(gòu)造方法
- OutputStreamWriter(OuputStream out):接收所有的字節(jié)輸出流
字節(jié)輸出流目前只有: FileOutputStream
- OutputStreamWriter(OutputStream out, String charsetName)
String charsetName:傳遞 編碼表名字:GBK、UTF-8
public class OutputStreamWriterDemo {public static void main(String[] args) throws IOException {writeUTF();}//轉(zhuǎn)換流對象OutputStreamWriter寫文本,采用UTF-8編碼表寫入public static void writeUTF()throws IOException{//創(chuàng)建字節(jié)輸出流,綁定文件FileOutputStream fos = new FileOutputStream("c:\\utf.txt");//創(chuàng)建轉(zhuǎn)換流對象,構(gòu)造方法保證字節(jié)輸出流,并指定編碼表是UTF-8OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); //GBK可以不寫osw.write("你好");osw.close(); //使用close()連刷新帶關(guān)閉} }2. InputStreamReader 類
(1) 概述
- java.io.InputStreamReader繼承 Reader;是 字符輸入流,讀取文本文件
- 字節(jié)流向字符的橋梁,將 字節(jié)流 轉(zhuǎn)為 字符流
- 讀取的方法:read() 讀取1個(gè)字符,讀取字符數(shù)組
(2) 構(gòu)造方法
- InputStreamReader(InputStream in):接收所有的 字節(jié)輸入流
可以傳遞的字節(jié)輸入流: FileInputStream
- InputStreamReader(InputStream in,String charsetName): 傳遞編碼表的名字
###3. 轉(zhuǎn)換流子類父類的區(qū)別
- 繼承關(guān)系
OutputStreamWriter 的子類: FileWriter
InputStreamReader 的子類:FileReader - 區(qū)別
- OutputStreamWriter 和 InputStreamReader 是字符和字節(jié)的橋梁:也可以稱之為字符轉(zhuǎn)換流。字符轉(zhuǎn)換流原理:字節(jié)流 + 編碼表
- FileWriter 和 FileReader:作為子類,僅作為操作字符文件的便捷類存在。當(dāng)操作的字符文件,使用的是默認(rèn)編碼表時(shí)可以不用父類,而直接用子類就完成操作了,簡化了代碼。
- 以下三句話功能相同
InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”));//默認(rèn)字符集。
InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”),“GBK”);//指定GBK字符集。
FileReader fr = new FileReader(“a.txt”);
注意:一旦要指定其他編碼時(shí),絕對不能用子類,必須使用字符轉(zhuǎn)換流。什么時(shí)候用子類呢?
條件:1、操作的是文件。2、使用默認(rèn)編碼。
二、字節(jié)緩沖流
1. 概述
- 可提高IO流的讀寫速度
- 分為字節(jié)緩沖流與字符緩沖流
2. 字節(jié)輸出緩沖流 BufferedOutputStream
- java.io.BufferedOuputStream作用: 提高原有輸出流的寫入效率
- BufferedOuputStream 繼承 OutputStream
- 方法:寫入 write 字節(jié),字節(jié)數(shù)組
- 構(gòu)造方法:BufferedOuputStream(OuputStream out):可以傳遞任意的字節(jié)輸出流,傳遞的是哪個(gè)字節(jié)流,就對哪個(gè)字節(jié)流提高效率
3. 字節(jié)輸入緩沖流 BufferedInputStream
- BufferedInputStream,繼承 InputStream ,標(biāo)準(zhǔn)的字節(jié)輸入流
- 讀取方法: read() ,單個(gè)字節(jié),字節(jié)數(shù)組
- 構(gòu)造方法: BufferedInputStream(InputStream in):可以傳遞任意的字節(jié)輸入流,傳遞是誰,就提高誰的效率
- 可以傳遞的字節(jié)輸入流 FileInputStream
4. 四種文件復(fù)制方式的效率比較
- 結(jié)論:
- 字節(jié)流讀寫單個(gè)字節(jié) :125250 毫秒
- 字節(jié)流讀寫字節(jié)數(shù)組 :193 毫秒
- 字節(jié)流緩沖區(qū)流讀寫單個(gè)字節(jié):1210 毫秒
- 字節(jié)流緩沖區(qū)流讀寫字節(jié)數(shù)組 :73 毫秒
- 代碼
三、字符緩沖流
1. 字符輸出緩沖流 BufferedWriter
- java.io.BufferedWriter繼承 Writer
- 寫入方法: write () ,單個(gè)字符,字符數(shù)組,字符串
- 構(gòu)造方法:BufferedWriter(Writer w):傳遞任意字符輸出流,傳遞誰,就高效誰
- 能傳遞的字符輸出流: FileWriter, OutputStreamWriter
2. 字符輸出緩沖流 BufferedWriter—特有方法 newLine
- void newLine(): 寫換行
- newLine():文本中換行, \r\n也是文本換行
- 方法具有平臺(tái)無關(guān)性
windows \r\n ; Linux \n
- newLine()運(yùn)行結(jié)果和操作系統(tǒng)是相互關(guān)聯(lián)的
- JVM: 安裝的是 Windows 版本,newLine()寫的就是 \r\n;安裝的是 Linux 版本,newLine() 寫的就是**\n**
3.字符輸入流緩沖流 BufferedReader
(1)概述
- java.io.BufferedReader繼承 Reader,從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取
讀取功能: read(), 單個(gè)字符,字符數(shù)組
構(gòu)造方法:BufferedReader(Reader r):可以任意的字符輸入流,有:FileReaderInputStreamReader
(2)BufferedReader 自己的功能
- String readLine(): 讀取文本行 \r\n ,讀取一個(gè)文本行,包含該行內(nèi)容的字符串,不包含任何行終止符,如果已到達(dá)流末尾,則返回 null
獲取內(nèi)容的方法一般都有返回值
int:沒有返回的都是 負(fù)數(shù)
引用類型: 找不到返回 null
boolean: 找不到返回 false
4. 字符流緩沖區(qū)流復(fù)制文本文件
/** 使用緩沖區(qū)流對象,復(fù)制文本文件* 數(shù)據(jù)源 BufferedReader+FileReader 讀取* 數(shù)據(jù)目的 BufferedWriter+FileWriter 寫入* 讀取文本行, 讀一行,寫一行,寫換行*/ public class Copy_1 {public static void main(String[] args) throws IOException{BufferedReader bfr = new BufferedReader(new FileReader("c:\\w.log")); BufferedWriter bfw = new BufferedWriter(new FileWriter("d:\\w.log"));//讀取文本行, 讀一行,寫一行,寫換行String line = null;while((line = bfr.readLine())!=null){bfw.write(line);bfw.newLine();bfw.flush();}bfw.close();bfr.close();} }四、序列化流與反序列化流
1. 概述
- 對象的序列化:對象中的數(shù)據(jù),以流的形式,寫入到文件中保存過程稱為寫出對象,ObjectOutputStream將對象寫道文件中,實(shí)現(xiàn)序列化
- 對象的反序列化:在文件中,以流的形式,將對象讀出來,讀取對象,ObjectInputStream將文件對象讀取出來
2. 實(shí)現(xiàn)
- ObjectOutputStream: 寫對象,實(shí)現(xiàn)序列化
- 構(gòu)造方法:ObjectOutputStream(OutputSteam out):傳遞任意的 字節(jié)輸出流
- void writeObject(Object obj):寫出對象
- ObjectInputStream:讀取對象,實(shí)現(xiàn)反序列化
- 構(gòu)造方法:ObjectInputStream(InputStream in):傳遞任意的 字節(jié)輸入流,輸入流封裝文件,必須是序列化的文件
- Object readObject(): 讀取對象
3. 細(xì)節(jié)
(1)transient 瞬態(tài)關(guān)鍵字
- 作用: 被 transient修飾的屬性不會(huì)被序列化
- transient關(guān)鍵字只能修飾成員變量
(2)靜態(tài)不能序列化
- 原因:序列化是把對象數(shù)據(jù)進(jìn)行持久化存儲(chǔ);靜態(tài)的東西不屬于對象,而屬于類
(3)Serializable 接口
- 作用:給需要序列化的類上加標(biāo)記。該標(biāo)記中沒有任何抽象方法;只有實(shí)現(xiàn)了 Serializable接口的類的對象才能被序列化
4. 序列化中的序列號(hào)沖突問題
-
問題產(chǎn)生: 當(dāng)一個(gè)類實(shí)現(xiàn)Serializable接口后,創(chuàng)建對象并將對象寫入文件,之后更改了源代碼 (比如:將成員變量的修飾符有private改成public),再次從文件中讀取對象時(shí)會(huì)報(bào)異常
-
原因:一旦修改了源碼,重新編譯產(chǎn)生class文件,會(huì)根據(jù)類的成員重新計(jì)算序列號(hào),這樣新編譯的class文件中的序列號(hào),與原來文件中的序列號(hào)就不同了
-
解決:需要做一個(gè)終身不變的序列號(hào)! 需要在序列化中自定義序列號(hào)
五、打印流
1. 概述
- 打印流添加輸出數(shù)據(jù)的功能,使它們能夠方便地打印各種數(shù)據(jù)值表示形式.
2. 打印流根據(jù)流的分類
- 字節(jié)打印流 PrintStream
- 字符打印流 PrintWriter
3. 方法
- void print(String str): 輸出任意類型的數(shù)據(jù),
- void println(String str): 輸出任意類型的數(shù)據(jù),自動(dòng)寫入換行操作
4. 特點(diǎn)
- 此流不負(fù)責(zé)數(shù)據(jù)源,只負(fù)責(zé)數(shù)據(jù)目的
- 可以操作任意類型的數(shù)據(jù)。(boolean, int, long, float, double)
- 打印流,可以開啟自動(dòng)刷新功能
滿足兩個(gè)條件:- 使用特定的構(gòu)造方法,打開打印流的自動(dòng)刷新,輸出的數(shù)據(jù)目的必須是流對象:OutputStreamWriter
- 必須調(diào)用 println,printf,format三個(gè)方法中的一個(gè),啟用自動(dòng)刷新
- 為其他輸出流,添加功能
- 永遠(yuǎn)不會(huì)拋出 IOException,但是可能拋出別的異常
5. 構(gòu)造方法
- 就是打印流的輸出目的端
- PrintStream構(gòu)造方法
- 接收File類型,接收字符串文件名,接收字節(jié)輸出流OutputStream
- PrintWriter構(gòu)造方法
- 接收File類型,接收字符串文件名,接收字節(jié)輸出流OutputStream, 接收字符輸出流Writer
6. 打印字符數(shù)組
- println數(shù)組,只有打印字符數(shù)組時(shí)是打印內(nèi)容,其余均打印數(shù)組的地址
- 因?yàn)閍pi中定義了打印字符數(shù)組的方法,其底層是在遍歷數(shù)組中的元素,而其他打印數(shù)組的方法,都是將數(shù)組對象編程Object,其底層再將對象編程String,調(diào)用了 String s = String.valueOf(x);方法
7. 利用打印流,完成文本文件的復(fù)制
/** 打印流實(shí)現(xiàn)文本復(fù)制* 讀取數(shù)據(jù)源 BufferedReader+File 讀取文本行* 寫入數(shù)據(jù)目的 PrintWriter+println 自動(dòng)刷新*/ public class PrintWriterDemo1 {public static void main(String[] args) throws IOException{BufferedReader bfr = new BufferedReader(new FileReader("c:\\a.txt"));PrintWriter pw = new PrintWriter(new FileWriter("d:\\a.txt"),true);String line = null;while((line = bfr.readLine())!=null){pw.println(line);}pw.close();bfr.close();} }六、標(biāo)準(zhǔn)輸入、輸出流
1. 概述
- 標(biāo)準(zhǔn)輸入流: System.in默認(rèn)指鍵盤輸入
- 標(biāo)準(zhǔn)輸出流: System.out向顯示器輸出
2. 繼承關(guān)系
- PrintStream extends FilterOutputStream
- FilterOutputStream extends OutputStream
3. 案例
public class StandardIO {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String s;// 標(biāo)準(zhǔn)輸入流的read方法,讀取鍵盤數(shù)據(jù)的時(shí)候,當(dāng)當(dāng)前沒有鍵盤輸入數(shù)據(jù)的時(shí)候// read會(huì)阻塞當(dāng)前線程,使得不能結(jié)束,只有自定義協(xié)議,才能結(jié)束標(biāo)準(zhǔn)輸入流while((s = br.readLine()) != null) {//自定協(xié)議,當(dāng)用戶輸入886結(jié)束接收用戶輸入if("886".equals(s)) {break;}System.out.println("輸出:" + s);}br.close();} }七、IO流總結(jié)
- 字節(jié)流
- 字節(jié)輸入流 InputStream
- FileInputStream 操作文件的字節(jié)輸入流
- BufferedInputStream高效的字節(jié)輸入流
- ObjectInputStream 反序列化流
- 字節(jié)輸出流 OutputStram
- FileOutputStream 操作文件的字節(jié)輸出流
- BufferedOutputStream 高效的字節(jié)輸出流
- ObjectOuputStream 序列化流
- PrintStream 字節(jié)打印流
- 字節(jié)輸入流 InputStream
- 字符流
- 字符輸入流 Reader
- FileReader 操作文件的字符輸入流
- BufferedReader 高效的字符輸入流
- InputStreamReader 輸入操作的轉(zhuǎn)換流(把字節(jié)流封裝成字符流)
- 字符輸出流 Writer
- FileWriter 操作文件的字符輸出流
- BufferedWriter 高效的字符輸出流
- OutputStreamWriter 輸出操作的轉(zhuǎn)換流(把字節(jié)流封裝成字符流)
- PrintWriter 字符打印流
- 字符輸入流 Reader
- 方法:
- 讀數(shù)據(jù)方法:
- read() 一次讀一個(gè)字節(jié)或字符的方法
- read(byte[] char[]) 一次讀一個(gè)數(shù)組數(shù)據(jù)的方法
- readLine() 一次讀一行字符串的方法(BufferedReader類特有方法)
- readObject() 從流中讀取對象(ObjectInputStream特有方法)
- 寫數(shù)據(jù)方法:
- write(int) 一次寫一個(gè)字節(jié)或字符到文件中
- write(byte[] char[]) 一次寫一個(gè)數(shù)組數(shù)據(jù)到文件中
- write(String) 一次寫一個(gè)字符串內(nèi)容到文件中
- writeObject(Object ) 寫對象到流中(ObjectOutputStream類特有方法)
- newLine() 寫一個(gè)換行符號(hào)(BufferedWriter類特有方法)
- 讀數(shù)據(jù)方法:
- 向文件中寫入數(shù)據(jù)的過程
1,創(chuàng)建輸出流對象
2,寫數(shù)據(jù)到文件
3,關(guān)閉輸出流 - 從文件中讀數(shù)據(jù)的過程
1, 創(chuàng)建輸入流對象
2, 從文件中讀數(shù)據(jù)
3, 關(guān)閉輸入流 - 文件復(fù)制的過程
1, 創(chuàng)建輸入流(數(shù)據(jù)源)
2, 創(chuàng)建輸出流(目的地)
3, 從輸入流中讀數(shù)據(jù)
4, 通過輸出流,把數(shù)據(jù)寫入目的地
5, 關(guān)閉流
File類
- 方法
- 獲取文件名稱 getName()
- 獲取文件絕對路徑 getAbsolutePath()
- 獲取文件大小 length()
- 獲取當(dāng)前文件夾中所有File對象 File[] listFiles()
- 判斷是否為文件 isFile()
- 判斷是否為文件夾 isDirectory()
- 創(chuàng)建文件夾 mkdir() mkdirs()
- 創(chuàng)建文件 createNewFile()
- 異常
- try…catch…finally捕獲處理異常
- throws 聲明異常
- throw 拋出異常對象
- 異常的分類
- 編譯期異常 Exception
- 運(yùn)行期異常 RuntimeException
- 注意:
- 編譯期異常,必須處理,不然無法編譯通過
- 運(yùn)行期異常,程序運(yùn)行過程中,產(chǎn)生的異常信息
- 實(shí)現(xiàn)文件內(nèi)容的自動(dòng)追加
- 構(gòu)造方法
- FileOutputStream(File file, boolean append)
- FileOutputStream(String fileName, boolean append)
- FileWriter(File, boolean append)
- FileWriter(String fileName, boolean append)
- 構(gòu)造方法
- 實(shí)現(xiàn)文件內(nèi)容的自動(dòng)刷新
- 構(gòu)造方法
- PrintStream(OutputStream out, boolean autoFlush)
- PrintWriter(OutputStream out, boolean autoFlush)
- 構(gòu)造方法
- 異常
- try…catch…finally捕獲處理異常
- throws 聲明異常
- throw 拋出異常對象
- 異常的分類
- 編譯期異常 Exception
- 運(yùn)行期異常 RuntimeException
- 注意:
- 編譯期異常,必須處理,不然無法編譯通過
- 運(yùn)行期異常,程序運(yùn)行過程中,產(chǎn)生的異常信息
- 實(shí)現(xiàn)文件內(nèi)容的自動(dòng)追加
- 構(gòu)造方法
- FileOutputStream(File file, boolean append)
- FileOutputStream(String fileName, boolean append)
- FileWriter(File, boolean append)
- FileWriter(String fileName, boolean append)
- 構(gòu)造方法
- 實(shí)現(xiàn)文件內(nèi)容的自動(dòng)刷新
- 構(gòu)造方法
- PrintStream(OutputStream out, boolean autoFlush)
- PrintWriter(OutputStream out, boolean autoFlush)
- 構(gòu)造方法
總結(jié)
以上是生活随笔為你收集整理的Java-进阶:Java-File--IO—2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不孕不育主要做哪几项检查
- 下一篇: Java-进阶:多线程1