1、
1 package cn.kongxh.io3; 2 3 import java.io.File ; 4 import java.io.Writer ; 5 import java.io.FileWriter ; 6 import java.io.OutputStreamWriter; 7 public class WriterDemo01{ 8 public static void main(String args[]) throws Exception{ // 異常拋出,不處理 9 // 第1步、使用File類找到一個文件 10 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 11 // 第2步、通過子類實例化父類對象 12 Writer out = null ; // 准備好一個輸出的對象 13 out = new FileWriter(f) ; // 通過對象多態性,進行實例化 14 // 第3步、進行寫操作 15 String str = "Hello World!!!" ; // 准備一個字符串 16 out.write(str) ; // 將內容輸出,保存文件 17 // 第4步、關閉輸出流 18 out.close() ; // 關閉輸出流 19 //public class FileWriter extends OutputStreamWriter 20 //public class OutputStreamWriter extends Writer FileWriter實際上繼承自 OutputStreamWriter 21 } 22 };
2、
1 package cn.kongxh.io3; 2 3 import java.io.File ; 4 import java.io.Writer ; 5 import java.io.FileWriter ; 6 public class WriterDemo02{ 7 public static void main(String args[]) throws Exception{ // 異常拋出,不處理 8 // 第1步、使用File類找到一個文件 9 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 10 // 第2步、通過子類實例化父類對象 11 Writer out = null ; // 准備好一個輸出的對象 12 out = new FileWriter(f,true) ; // 通過對象多態性,進行實例化 13 // 第3步、進行寫操作 14 String str = "\r\nLIXINGHUA\r\nHello World!!!" ; // 准備一個字符串 15 out.write(str) ; // 將內容輸出,保存文件 16 // 第4步、關閉輸出流 17 out.close() ; // 關閉輸出流 18 } 19 };
3、
1 package cn.kongxh.io3; 2 3 import java.io.File ; 4 import java.io.Writer ; 5 import java.io.FileWriter ; 6 public class WriterDemo03{ 7 public static void main(String args[]) throws Exception{ // 異常拋出,不處理 8 // 第1步、使用File類找到一個文件 9 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 10 // 第2步、通過子類實例化父類對象 11 Writer out = null ; // 准備好一個輸出的對象 12 out = new FileWriter(f) ; // 通過對象多態性,進行實例化 13 // 第3步、進行寫操作 14 String str = "Hello World!!!" ; // 准備一個字符串 15 out.write(str) ; // 將內容輸出,保存文件 16 // 第4步、關閉輸出流 17 // out.close() ; // 此時,沒有關閉 18 /* 19 * 不關閉 不會寫入到文件中 證明還在緩存區,沒有刷到文件中 如果關閉流(out.close();) 會強制刷新緩存區 20 * */ 21 } 22 };
4、
1 package cn.kongxh.io3; 2 3 import java.io.File ; 4 import java.io.Writer ; 5 import java.io.FileWriter ; 6 public class WriterDemo04{ 7 public static void main(String args[]) throws Exception{ // 異常拋出,不處理 8 // 第1步、使用File類找到一個文件 9 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 10 // 第2步、通過子類實例化父類對象 11 Writer out = null ; // 准備好一個輸出的對象 12 out = new FileWriter(f) ; // 通過對象多態性,進行實例化 13 // 第3步、進行寫操作 14 String str = "Hello World!!!" ; // 准備一個字符串 15 out.write(str) ; // 將內容輸出,保存文件 16 // 第4步、關閉輸出流 17 out.flush() ; // 強制性清空緩沖區中的內容 18 // out.close() ; // 此時,沒有關閉 19 } 20 };
5、案例
1 package cn.kongxh.io3; 2 import java.io.* ; 3 public class Copy{ 4 public static void main(String args[]){ 5 if(args.length!=2){ // 判斷是否是兩個參數 6 System.out.println("輸入的參數不正確。") ; 7 System.out.println("例:java Copy 源文件路徑 目標文件路徑") ; 8 System.exit(1) ; // 系統退出 9 } 10 File f1 = new File(args[0]) ; // 源文件的File對象 11 File f2 = new File(args[1]) ; // 目標文件的File對象 12 if(!f1.exists()){ 13 System.out.println("源文件不存在!") ; 14 System.exit(1) ; 15 } 16 InputStream input = null ; // 准備好輸入流對象,讀取源文件 17 OutputStream out = null ; // 准備好輸出流對象,寫入目標文件 18 try{ 19 input = new FileInputStream(f1) ; 20 }catch(FileNotFoundException e){ 21 e.printStackTrace() ; 22 } 23 try{ 24 out = new FileOutputStream(f2) ; 25 }catch(FileNotFoundException e){ 26 e.printStackTrace() ; 27 } 28 if(input!=null && out!=null){ // 判斷輸入或輸出是否准備好 29 int temp = 0 ; 30 try{ 31 while((temp=input.read())!=-1){ // 開始拷貝 32 out.write(temp) ; // 邊讀邊寫 33 } 34 System.out.println("拷貝完成!") ; 35 }catch(IOException e){ 36 e.printStackTrace() ; 37 System.out.println("拷貝失敗!") ; 38 } 39 try{ 40 input.close() ; // 關閉 41 out.close() ; // 關閉 42 }catch(IOException e){ 43 e.printStackTrace() ; 44 } 45 } 46 } 47 }
總結:
文件IO操作、字節流和字符流
無緩沖區 阻塞
實際上字節流在操作時本身不會用到緩沖區(內存),是文件本身直接操作的,而字符流在操作時使用了緩沖區,通過緩沖區再操作文件
提問:什么叫緩沖區?
在很多地方都碰到緩沖區這個名詞,那么到底什么是緩沖區?又有什么作用呢?
回答:緩沖區可以簡單地理解為一段內存區域。
可以簡單地把緩沖區理解為一段特殊的內存。
某些情況下,如果一個程序頻繁地操作一個資源(如文件或數據庫),則性能會很低,此時為了提升性能,就可以將一部分數據暫時讀入到內存的一塊區域之中,以后直接從此區域中讀取數據即可,因為讀取內存速度會比較快,這樣可以提升程序的性能。
在字符流的操作中,所有的字符都是在內存中形成的,在輸出前會將所有的內容暫時保存在內存之中,所以使用了緩沖區暫存數據。
如果想在不關閉時也可以將字符流的內容全部輸出,則可以使用Writer類中的flush()方法完成。
在回答之前,先為讀者講解這樣的一個概念,所有的文件在硬盤或在傳輸時都是以字節的方式進行的,包括圖片等都是按字節的方式存儲的,而字符是只有在內存中才會形成,所以在開發中,字節流使用較為廣泛。
字節流與字符流主要的區別是他們的的處理方式
流分類:
1.Java的字節流
InputStream是所有字節輸入流的祖先,而OutputStream是所有字節輸出流的祖先。
2.Java的字符流(字符只存在內存里)
Reader是所有讀取字符串輸入流的祖先,而writer是所有輸出字符串的祖先。
InputStream,OutputStream,Reader,writer都是抽象類。所以不能直接new
字節流是最基本的,所有的InputStream和OutputStream的子類都是,主要用在處理二進制數據,它是按字節來處理的
但實際中很多的數據是文本,又提出了字符流的概念,它是按虛擬機的encode來處理,也就是要進行字符集的轉化
這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯
在實際開發中出現的漢字問題實際上都是在字符流和字節流之間轉化不統一而造成的
在從字節流轉化為字符流時,實際上就是byte[]轉化為String時,
public String(byte bytes[], String charsetName)
有一個關鍵的參數字符集編碼,通常我們都省略了,那系統就用操作系統的lang
而在字符流轉化為字節流時,實際上是String轉化為byte[]時,
byte[] String.getBytes(String charsetName)
也是一樣的道理
至於java.io中還出現了許多其他的流,按主要是為了提高性能和使用方便,
如BufferedInputStream,PipedInputStream等