I/O流 技術 學習筆記



本文查閱方法:
    一、查閱目錄 —— 查閱本文目錄,肯定想要查閱的目錄標題
    二、快捷「查找」 —— 在當前瀏覽器頁面,按鍵 「Ctrl+F」 按鍵組合,開啓瀏覽器的查找功能,
             在查找搜索框中 輸入須要查閱的 目錄標題,即可以直接到達 標題內容 的位置。
    三、學習小結 —— 文中的學習小結內容,是筆者在學習以後總結出的,開發時可直接參考其進行應用開發的內容, 進一步加快了本文的查閱 速度。(水平有限,僅供參考。)

java

 

 

 

 

 


 

 

 

 

 

本文目錄linux

 

  學習小結算法

 

  一、IO(Input  Output)流 概述編程

 

    (1)IO流的簡介windows

 

    (2)IO流經常使用基類設計模式

 

    (3)IO程序的書寫流程數組

 

  二、字符流-- FileWriter瀏覽器

 

  三、處理IO輸出流異常的完整代碼安全

 

  四、文件的續寫多線程

 

  五、字符流--FileReader讀取文件的兩種方式

 

    (1)第一種方式:逐個字符地從文件中讀取數據

 

    (2)第二種方式:經過字符數組進行讀取。

 

    (3)注意事項:

 

  六、拷貝文本文件

 

  七、字符流的緩衝區 BufferedWriter 和 BufferedReader 

 

    (1)BufferedWriter -- 字符寫入流緩衝區

 

    (2)BufferedReader -- 字符讀取流緩衝區:

 

    (3)經過緩衝區複製文本文件

 

    (4)readLine的原理圖解

 

    (5)自定義ReadLine()方法

 

  八、採用「裝飾設計模式」的思想來改造IO流類----加強其功能。

 

    (1)裝飾設計模式 介紹

 

    (2)裝飾和繼承的區別

 

    (3)以LineNumberReader 類爲基礎裝飾設計模式應用Demo

 

  九、字節流FileInputStream / FileOutputStream 對文件的讀寫操做

 

    (1)InputStream / OutputStream 的基本操做 Demo

 

    (2)拷貝圖片 

 

  十、字節流的緩衝區: BufferedOutputStream / BufferedInputStream

 

    (1)複製mp3:演示緩衝區使用流程

 

    (2)自定義字節流的緩衝區-- 探尋read()和write()的特色

 

  十一、讀取鍵盤錄入: System.in

 

  十二、讀取/寫入 轉換流:InputStreamReader與OutputStreamWriter

 

    (1)標準輸入輸出

 

    (2)改變標準的輸入輸出設備

 

  1三、衆多IO流對象的選用規律

 

  1四、保存「異常信息」到日誌文件

 

  1五、File對象的建立、刪除、判斷、獲取等功能。

 

  1六、File對象 ———— 實現文件列表功能經常使用方法

 

  1七、File對象 —— 操做 文件列表/目錄

 

    (1)列出目錄下全部內容——遞歸方法(含帶層次展示)

 

    (2)刪除帶內容的目錄

 

    (3)建立展示多層級的Java文件列表並輸出到文件

 

  1八、Properties  存取配置文件

 

  1九、PrintStream 以及 PrintWriter

 

  20、文件的 切割操做

 

  2一、文件的合併操做 -----  SequenceInputStream 合併文件

 

  2二、對象的序列化:ObjectOutputStream 和反序列化:ObjectInputStream  

 

  2三、RandomAccessFile 隨機讀寫訪問文件

 

  2四、操做基本數據類型 DataInputStream與DataOutputStream

 

  2五、ByteArrayStream 操做字節數組的流對象。

 

  2六、字符的編碼和解碼

 

    (1)編碼 和 解碼 的練習

 

    (2)轉換流的字符編碼

 

  

 

 

 

 

 


 

 

 

 

 

學習小結

 

(1)字符流的輸入與輸出

 

   public  void test() //此種寫法雖然麻煩,可是效能高,也處理了異常,很是健壯,建議拷貝使用。

 

   {

 

      BufferedReader bufr = null;

 

      BufferedWriter bufw = null;

 

      try{

 

         bufr = new BufferedReader(new FileReader("Text1.java"));

 

         bufw = new BufferedWriter(new FileWriter("Text2.txt"));

 

         String line = null;

 

         while((line=bufr.readLine())!=null){

 

          bufw.write(line);

 

          bufw.newLine();  //寫入換行符。

 

          bufw.flush();

 

         }

 

      }catch (IOException e){

 

         throw new RuntimeException("讀寫失敗");

 

      }

 

      finally

 

      {

 

         try{

 

          if(bufr!=null)

 

            bufr.close();

 

         }catch (IOException e){

 

          throw new RuntimeException("讀取關閉失敗");

 

         }

 

         try{

 

          if(bufw!=null)

 

             bufw.close();

 

         }catch (IOException e){

 

          throw new RuntimeException("寫入關閉失敗");

 

         }

 

      }

 

   }

 

 

 

(2)字節流的輸入與輸出

 

    //採用了Buffered緩衝區,可是未考慮詳細異常的字節流讀取

 

    public static void copy_1()throws IOException{

 

      BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));

 

      BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));

 

 

 

      int by = 0;

 

      while((by=bufis.read())!=-1){

 

         bufos.write(by);

 

      }

 

      bufos.close();

 

      bufis.close();     

 

   }

 

 

 

  //未採用字節流緩衝區Buffered,可是處理了異常的字節流讀取。

 

   public static void main(String[] args){

 

      FileOutputStream fos = null;

 

      FileInputStream fis = null;

 

      try{

 

         fos = new FileOutputStream("c:\\2.bmp");

 

         fis = new FileInputStream("c:\\1.bmp");

 

 

 

    //=============== 開發時經常使用代碼片斷==================== 

 

         byte[] buf = new byte[1024];

 

         int len = 0;

 

         while((len=fis.read(buf))!=-1){

 

          fos.write(buf,0,len);

 

         }

 

    //=============== 開發時經常使用代碼片斷==================== 

 

 

 

      }catch (IOException e){

 

         throw new RuntimeException("複製文件失敗");

 

      }finally{

 

         try{

 

          if(fis!=null)

 

             fis.close();

 

         }catch (IOException e){

 

          throw new RuntimeException("讀取關閉失敗");

 

         }

 

 

 

         try{

 

          if(fos!=null)

 

             fos.close();

 

         }catch (IOException e){

 

          throw new RuntimeException("寫入關閉失敗");

 

         }

 

      }

 

   }

 

 

 

(3)Properties  讀取配置文件

 

    Properties prop = new Properties();

 

    FileInputStream fis = new FileInputStream("info.txt");

 

    prop.load(fis);  //將流中的數據加載進集合。

 

    String value = prop.getProperty("lisi");  //取出屬性值的操做

 

    fis.close();

 

 

 

 

 

(4)File對象的建立、判斷

 

    FileInputStream fis = null;//注:該輸入流 根據實際狀況 賦值。

 

    File dir = new File("abc\\kkk\\a");//你講文件放置到該目錄下面。

 

    if(!dir.exists()){  //判斷該目錄是否已實際存在

 

      dir.mkdirs();  //若不存在,則建立出實際目錄

 

    }

 

    File newFile=new File(dir,"newText.jpg");  //將目標目錄與擬存放後的新文件名建立新的文件絕對路徑

 

    FileOutputStream fos =new FileOutputStream(newFile);

 

    byte[] buf = new byte[1024];

 

      int len = 0;

 

      while((len=fis.read(buf))!=-1){

 

      fos.write(buf,0,len);    //向新的文件中寫入數據。

 

      }

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

一、IO(Input  Output)流 概述

 

  (1)IO流的簡介 

 

    簡介:IO流用來處理設備之間的數據傳輸,Java對數據的操做是經過流的方式,Java用於操做流的對象都在IO包中 

 

    分類:流按操做數據分爲兩種:字節流與字符流。 

 

         流按流向分爲:輸入流,輸出流。 

 

  (2)IO流經常使用基類 

 

    字節流的抽象基類: 

 

      InputStream ,OutputStream。 

 

    字符流的抽象基類: 

 

      Reader ,Writer 。 

 

    注:由這四個類派生出來的子類名稱都是 

 

       以其父類名做爲子類名的後綴。 

 

           如:InputStream的子類FileInputStream。 

 

           如:Reader的子類FileReader。 

 

  (3)IO程序的書寫流程 

 

    導入IO包中的類 

 

    編寫IO代碼

 

    進行IO異常處理 

 

    在finally 中對流進行關閉 

 

 

 

 

 


 

 

 

 

 

二、字符流-- FileWriter

 

  FileWriter是專門用於操做文件的Writer子類對象。FileWriter。  後綴名是父類名。 前綴名是該流對象的功能。

 

    語法:  

 

    建立流對象,創建數據存放文件 

 

      • FileWriter fw = new FileWriter(「Test.txt」); 

 

    調用流對象的寫入方法,將數據寫入流 

 

      • fw.write(「text」); 

 

    關閉流資源,並將流中的數據清空到文件中。 

 

      • fw.close(); 

 

 

 

  Demo以下:

 

  class  FileWriterDemo

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        //建立一個FileWriter對象。該對象一被初始化就必需要明確被操做的文件。

 

        //並且該文件會被建立到指定目錄下。若是該目錄下已有同名文件,將被覆蓋。

 

        //其實該步就是在明確數據要存放的目的地。

 

        FileWriter fw = new FileWriter("demo.txt");

 

        //調用write方法,將字符串寫入到流中。

 

        fw.write("abcde");

 

        //刷新流對象中的緩衝中的數據。

 

        //將數據刷到目的地中。

 

        //fw.flush();

 

 

 

        //關閉流資源,可是關閉以前會刷新一次內部的緩衝中的數據。

 

        //將數據刷到目的地中。

 

        //和flush區別:flush刷新後,流能夠繼續使用,close刷新後,會將流關閉。

 

        fw.close();

 

     }

 

  }

 

 

 

 

 


 

 

 

 

 

三、處理IO輸出流異常的完整代碼

 

    這是處理寫文件時控制異常的完整代碼,建議咱們在實際開發中,儘可能寫這種代碼,將會是代碼更加的嚴謹和健壯。 

 

              FileWriter fw = null; 

 

              try{ 

 

                  fw = new FileWriter("Test.txt"); 

 

                  fw.write("text"); 

 

              } 

 

              catch (IOException e){ 

 

                  System.out.println(e.toString()); 

 

              } 

 

              finally{ 

 

                  If(fw!=null) 

 

                  try{ 

 

            fw.close(); 

 

          }catch (IOException e){ 

 

            System.out.println(e.toString()); 

 

          } 

 

              } 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

四、文件的續寫

 

  在開發中,向已經存在的文件的末尾,繼續續寫數據的功能很是重要,下面兩個構造函數能夠實現:

 

    FileWriter(String fileName, boolean append) 

 

    FileOutputStream(String name, boolean append)

 

    根據給定的文件名以及指示是否附加寫入數據的 boolean 值來構造 FileWriter/FileOutputStream對象

 

 

 

  Demo樣例:

 

    FileWriter  fw=new FileWriter("demo.txt",true);

 

    fw.write("nihao\r\n xiexie");    //在文件中寫入換行顯示的數據,

 

    fw.close();     //windows的記事本里識別的換行符,僅支持 \r\n, 

 

              //而linux等系統以及 EditPlus 中則支持\n換行。

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

五、字符流--FileReader讀取文件的兩種方式

 

  (1)第一種方式:逐個字符地從文件中讀取數據

 

    Demo:

 

    class  FileReaderDemo

 

    {

 

       public static void main(String[] args) throws IOException{

 

          //建立一個文件讀取流對象,和指定名稱的文件相關聯。

 

          //要保證該文件是已經存在的,若是不存在,會發生異常FileNotFoundException

 

          FileReader fr = new FileReader("demo.txt");

 

          //調用讀取流對象的read方法。

 

          //read():一次讀一個字符。並且會自動往下讀。  

 

          int ch = 0;

 

          while((ch=fr.read())!=-1){

 

             System.out.println(

 

          }

 

          /*

 

          while(true){

 

             int ch = fr.read();

 

             if(ch==-1)

 

            break;

 

             System.out.println("ch="+(char)ch);

 

          }

 

          */

 

          fr.close();

 

       }

 

    }

 

 

 

 逐個字符讀取文件原理圖解

 



 

 

 

 

  

 

 

 

  (2)第二種方式:經過字符數組進行讀取。

 

    Demo:

 

    class FileReaderDemo2 

 

    {

 

       public static void main(String[] args) throws IOException{

 

          FileReader fr = new FileReader("demo.txt");  

 

          //定義一個字符數組。用於存儲讀到字符。

 

          //該read(char[])返回的是讀到字符個數。

 

          char[] buf = new char[1024];

 

          int num = 0;

 

          while((num=fr.read(buf))!=-1){

 

             System.out.println(new String(buf,0,num));

 

          }  

 

          fr.close();

 

       }

 

    }

 

 

 

字符數組進行讀取文件圖解 



 

 

 

 

 

 

 

 

  (3)注意事項:

 

    a.定義文件路徑時,能夠用「/」或者「\\」 。 

 

    b.在建立一個文件時,若是目錄下有同名文件將被覆蓋。 

 

    c.在讀取文件時,必須保證該文件已存在,不然出異常。 

 

 

 

  

 


 

 

 

 

 

六、拷貝文本文件

 

  拷貝文本文件原理:是有兩個過程完成的。

 

    (1)讀取數據:讀取源文件中的數據到內存中。

 

    (2)寫入數據:將讀到的數據從內存中寫入到目標位置一個文件中。

 

 

 

  示例剖析:將C盤一個文本文件複製到D盤。

 

    複製的原理:

 

    其實就是將C盤下的文件數據存儲到D盤的一個文件中。

 

    步驟:

 

    1,在D盤建立一個文件。用於存儲C盤文件中的數據。

 

    2,定義讀取流和C盤文件關聯。

 

    3,經過不斷的讀寫完成數據存儲。

 

    4,關閉資源。

 

 

 

  示例Demo:

 

  class CopyText 

 

  {

 

     public static void main(String[] args) throws IOException{

 

        copy_2();

 

     }

 

 

 

     public static void copy_2(){

 

        FileWriter fw = null;

 

        FileReader fr = null;

 

        try{

 

           fw = new FileWriter("SystemDemo_copy.txt");

 

           fr = new FileReader("SystemDemo.java");

 

           char[] buf = new char[1024];

 

           int len = 0;

 

           while((len=fr.read(buf))!=-1){

 

            fw.write(buf,0,len);

 

           }

 

        }catch (IOException e){

 

           throw new RuntimeException("讀寫失敗");

 

        }finally{

 

           if(fr!=null)

 

            try{

 

             fr.close();

 

            }catch (IOException e){     }

 

           if(fw!=null)

 

            try{

 

             fw.close();

 

            }catch (IOException e){    }

 

        }

 

     }

 

     //從C盤讀一個字符,就往D盤寫一個字符。

 

     public static void copy_1()throws IOException

 

     {

 

        //建立目的地。

 

        FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");

 

        //與已有文件關聯。

 

        FileReader fr = new FileReader("RuntimeDemo.java");

 

        int ch = 0;

 

        while((ch=fr.read())!=-1){

 

           fw.write(ch);

 

        }  

 

        fw.close();

 

        fr.close();

 

     }

 

  }

 

 

 

 

 

 文件複製過程圖例

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

七、字符流的緩衝區 BufferedWriter 和 BufferedReader 

 

 

 

  緩衝區的出現提升了對數據的讀寫效率,要結合流纔可使用。是在流的基礎上對流的功能進行了加強。 

 

    對應類 

 

      BufferedWriter  -- 字符寫入流緩衝區

 

      BufferedReader  -- 字符讀取流緩衝區

 

  緩衝區是爲了提升流的操做效率而出現的。因此在建立緩衝區以前,必需要先有流對象。

 

 

 

  (1)BufferedWriter -- 字符寫入流緩衝區

 

    備註:該緩衝區中提供了一個跨平臺的換行符。newLine();

 

 

 

    示例Demo:

 

      class  BufferedWriterDemo

 

      {

 

         public static void main(String[] args) throws IOException

 

         {

 

            //建立一個字符寫入流對象。

 

            FileWriter fw = new FileWriter("buf.txt");

 

            //爲了提升字符寫入流效率。加入了緩衝技術。

 

            //只要將須要被提升效率的流對象做爲參數傳遞給緩衝區的構造函數便可。

 

            BufferedWriter bufw = new BufferedWriter(fw);

 

            for(int x=1; x<5; x++){

 

               bufw.write("abcd"+x);

 

               bufw.newLine();//若要在寫入的文本中實現換行格式的效果,就須要調用newLine()方法寫入換行符。

 

               bufw.flush();

 

            }

 

            //記住,只要用到緩衝區,就要記得刷新。

 

            //bufw.flush();

 

            //其實關閉緩衝區,就是在關閉緩衝區中的流對象。

 

            bufw.close();

 

         }

 

      }

 

 

 

 

 

 

 

  (2)BufferedReader -- 字符讀取流緩衝區:

 

    該緩衝區提供了一個一次讀一行的方法 readLine,方便於對文本數據的獲取。

 

    當返回null時,表示讀到文件末尾。

 

    備註:readLine方法返回的時候只返回回車符以前的數據內容,並不返回回車符。

 

 

 

    示例Demo:

 

    class  BufferedReaderDemo

 

    {

 

        public static void main(String[] args) throws IOException{

 

          //建立一個讀取流對象和文件相關聯。

 

          FileReader fr = new FileReader("buf.txt");

 

          //爲了提升效率。加入緩衝技術。將字符讀取流對象做爲參數傳遞給緩衝對象的構造函數。

 

          BufferedReader bufr = new BufferedReader(fr);

 

 

 

          String line = null;

 

          while((line=bufr.readLine())!=null){

 

             System.out.print(line);

 

          }

 

          bufr.close();

 

        }

 

    }   

 

 

 

 

 

  (3)經過緩衝區複製文本文件

 

 

 

    示例Demo:

 

    //需求:經過緩衝區複製一個.java文件。

 

    class  CopyTextByBuf

 

    {

 

       public static void main(String[] args) 

 

       {

 

          BufferedReader bufr = null;

 

          BufferedWriter bufw = null;

 

          try{

 

             bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));

 

             bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));

 

             String line = null;

 

             while((line=bufr.readLine())!=null){

 

              bufw.write(line);

 

              bufw.newLine();  //若要在寫入的文本中實現換行格式的效果,就須要調用newLine()方法寫入換行符。

 

              bufw.flush();

 

             }

 

          }catch (IOException e){

 

             throw new RuntimeException("讀寫失敗");

 

          }

 

          finally

 

          {

 

             try{

 

              if(bufr!=null)

 

               bufr.close();

 

             }catch (IOException e){

 

              throw new RuntimeException("讀取關閉失敗");

 

             }

 

             try{

 

              if(bufw!=null)

 

               bufw.close();

 

             }catch (IOException e){

 

              throw new RuntimeException("寫入關閉失敗");

 

             }

 

          }

 

       }

 

    }

 

 

 

 

 

  (4)readLine的原理圖解

 

 

 

 

 

 

 

 

 

 

 

 

  (5)自定義ReadLine()方法

 

    明白了BufferedReader類中特有方法readLine的原理後,能夠自定義一個MyBufferedReader類中包含一個功能和readLine一致的方法。

 

來模擬一下BufferedReader

 

 

 

    示例Demo:

 

    class MyBufferedReader extends Reader

 

    { 

 

       private Reader r;

 

       MyBufferedReader(Reader r){

 

          this.r = r;

 

       }

 

       //能夠一次讀一行數據的方法。

 

       public String myReadLine()throws IOException{

 

          //定義一個臨時容器。原BufferReader封裝的是字符數組。

 

          //爲了演示方便。定義一個StringBuilder容器。由於最終仍是要將數據變成字符串。

 

          StringBuilder sb = new StringBuilder();

 

          int ch = 0;

 

          while((ch=r.read())!=-1){

 

             if(ch=='\r')

 

              continue;

 

             if(ch=='\n')

 

              return sb.toString();

 

             else

 

              sb.append((char)ch);

 

          }

 

          if(sb.length()!=0)

 

             return sb.toString();

 

          return null;  

 

       }

 

       /*

 

       覆蓋Reader類中的抽象方法。

 

       */

 

       public int read(char[] cbuf, int off, int len) throws IOException{

 

          return r.read(cbuf,off,len) ;

 

       }

 

       public void close()throws IOException{

 

          r.close();

 

       }

 

       public void myClose()throws IOException{

 

          r.close();

 

       }

 

    }

 

    class  MyBufferedReaderDemo

 

    {

 

       public static void main(String[] args) throws IOException{

 

          FileReader fr = new FileReader("buf.txt");

 

          MyBufferedReader myBuf = new MyBufferedReader(fr);

 

          String line = null;

 

          while((line=myBuf.myReadLine())!=null){

 

             System.out.println(line);

 

          }

 

          myBuf.myClose();

 

       }

 

    }

 

 

 

 

 

 

 


 

 

 

 

 

八、採用「裝飾設計模式」的思想來改造IO流類----加強其功能。

 

  (1)裝飾設計模式 介紹

 

    裝飾設計模式:當想要對已有的對象進行功能加強時,能夠定義類,將已有對象傳入,基於已有的功能,並提供增強功能。那麼自定義的該類稱爲裝飾類,這種加強類功能的方式稱之爲「裝飾設計模式」。

 

    裝飾類一般會經過構造方法接收被裝飾的對象,並基於被裝飾的對象的功能,提供更強的功能。

 

 

 

    示例Demo:

 

    class Person

 

    {

 

       public void chifan(){

 

          System.out.println("吃飯");

 

       }

 

    }

 

    class SuperPerson 

 

    {

 

       private Person p ;

 

       SuperPerson(Person p){

 

          this.p = p;

 

       }

 

       public void superChifan(){

 

          System.out.println("開胃酒");

 

          p.chifan();

 

          System.out.println("甜點");

 

          System.out.println("來一根");

 

       }

 

    } 

 

    class  PersonDemo

 

    {

 

       public static void main(String[] args){

 

          Person p = new Person();

 

          //p.chifan();

 

          SuperPerson sp = new SuperPerson(p);

 

          sp.superChifan();

 

       }

 

    }

 

 

 

 

 

  (2)裝飾和繼承的區別

 

    咱們使用裝飾類加強原有類功能的思想,與繼承的方式很類似,可是兩者在實際的使用中,是有着必定區別的

 

    下面以模擬 自定義加強Reader體系中的各類裝飾類 繼承關係 來分析 兩者的區別

 

      MyReader//專門用於讀取數據的類。

 

       |--MyTextReader

 

        |--MyBufferTextReader

 

       |--MyMediaReader

 

        |--MyBufferMediaReader

 

       |--MyDataReader

 

        |--MyBufferDataReader       

 

      Demo:

 

      class MyBufferReader

 

      {

 

         MyBufferReader(MyTextReader text){

 

 

 

        }

 

         MyBufferReader(MyMediaReader media){

 

 

 

        }

 

      }

 

 

 

      上面這個類擴展性不好,假若找到其參數的共同類型,經過多態的形式,能夠提升擴展性。

 

      Demo:

 

      class MyBufferReader extends MyReader

 

      {

 

         private MyReader r;

 

         MyBufferReader(MyReader r){

 

 

 

         }

 

      } 

 

      MyReader//專門用於讀取數據的類。

 

       |--MyTextReader

 

       |--MyMediaReader

 

       |--MyDataReader

 

       |--MyBufferReader

 

 

 

      之前是經過繼承將每個子類都具有緩衝功能,那麼繼承體系會複雜,並不利於擴展。如今優化思想,單獨描述一下緩衝內容,將須要被緩衝的對象,傳遞進來。也就是,誰須要被緩衝,誰就做爲參數傳遞給緩衝區,這樣繼承體系就變得很簡單,優化了體系結構。

 

 

 

      裝飾模式比繼承要靈活,避免了繼承體系臃腫,並且下降了類與類之間的關係。裝飾類由於加強已有對象,具有的功能和已有的是相同的,只不過提供了更強功能。因此裝飾類和被裝飾類一般是都屬於一個體系中的。       

 

 

 

  (3)以LineNumberReader 類爲基礎裝飾設計模式應用Demo

 

      示例Demo:LineNumberReader (跟蹤行號的緩衝字符輸入流) 與 自定義MyLineNumberReader

 

 

 

      //原 LineNumberReader 功能Demo

 

      class LineNumberReaderDemo 

 

      {

 

         public static void main(String[] args)throws IOException {

 

            FileReader fr = new FileReader("PersonDemo.java");

 

            LineNumberReader lnr = new LineNumberReader(fr);//跟蹤行號的緩衝字符輸入流

 

            String line = null;

 

            lnr.setLineNumber(100);// 設置當前行號。

 

            while((line=lnr.readLine())!=null){

 

               System.out.println(lnr.getLineNumber()+":"+line);//得到當前行號。

 

            }

 

            lnr.close();

 

         }

 

      } 

 

 

 

      //自定義 相似LineNumberReader 功能的類Demo

 

      class MyLineNumberReader 

 

      {

 

         private Reader r;

 

         private int lineNumber;

 

         MyLineNumberReader(Reader r){

 

            this.r = r;

 

         }

 

         public String myReadLine()throws IOException{

 

            lineNumber++;

 

            StringBuilder sb = new StringBuilder();

 

            int ch = 0;

 

            while((ch=r.read())!=-1){

 

               if(ch=='\r')

 

                continue;

 

               if(ch=='\n')

 

                return sb.toString();

 

               else

 

                sb.append((char)ch);

 

            }

 

            if(sb.length()!=0)

 

               return sb.toString();

 

            return null;

 

         }

 

         public void setLineNumber(int lineNumber){

 

            this.lineNumber = lineNumber;

 

         }

 

         public int getLineNumber(){

 

            return lineNumber;

 

         }

 

         public void myClose()throws IOException{

 

            r.close();

 

         }

 

      }

 

 

 

      //採用了裝飾模式的 MyLineNumberReader  Demo

 

      class MyLineNumberReader extends MyBufferedReader

 

      {

 

         private int lineNumber;

 

         MyLineNumberReader(Reader r){

 

            super(r);

 

         }

 

         public String myReadLine()throws IOException{

 

            lineNumber++;

 

            return super.myReadLine();

 

         }

 

         public void setLineNumber(int lineNumber){

 

            this.lineNumber = lineNumber;

 

         }

 

         public int getLineNumber(){

 

            return lineNumber;

 

         }

 

      }

 

 

 

      class  MyLineNumberReaderDemo

 

      {

 

         public static void main(String[] args) throws IOException{

 

            FileReader fr = new FileReader("copyTextByBuf.java");

 

            MyLineNumberReader mylnr = new MyLineNumberReader(fr);

 

            String line = null;

 

            mylnr.setLineNumber(100);

 

            while((line=mylnr.myReadLine())!=null){

 

               System.out.println(mylnr.getLineNumber()+"::"+line);

 

            }

 

            mylnr.myClose();

 

         }

 

      }

 

 

 

 

 

 

 


 

 

 

 

 

九、字節流FileInputStream / FileOutputStream 對文件的讀寫操做

 

  字節流:InputStream / OutputStream 的基本操做與字符流類相同 

 

    但它不只能夠操做字符,還能夠操做其餘媒體文件需求。例如想要操做圖片數據,這時就要用到字節流。

 

 

 

  (1)InputStream / OutputStream 的基本操做 Demo

 

    Demo樣例:

 

    class  FileStream

 

    {

 

       public static void main(String[] args) throws IOException{

 

          readFile_3();

 

       }

 

       public static void readFile_3()throws IOException{  //使用available()函數定義正好的緩衝區

 

          FileInputStream fis = new FileInputStream("fos.txt");

 

 

 

          //  int num = fis.available();

 

          byte[] buf = new byte[fis.available()];//定義一個剛恰好的緩衝區,不用在循環了,但有可能因文件太大形成內存溢出。

 

          fis.read(buf);

 

          System.out.println(new String(buf));

 

          fis.close();

 

       }

 

 

 

       public static void readFile_2()throws IOException{  //定義必定容量的緩衝區進行循環的讀取/寫入操做, 推薦使用的方式,高效又安全。

 

          FileInputStream fis = new FileInputStream("fos.txt");

 

          byte[] buf = new byte[1024];

 

          int len = 0;

 

          while((len=fis.read(buf))!=-1){

 

             System.out.println(new String(buf,0,len));

 

          }

 

          fis.close();  

 

       } 

 

       public static void readFile_1()throws IOException{  //逐個字節地讀取並寫入數據到文件。

 

          FileInputStream fis = new FileInputStream("fos.txt");

 

          int ch = 0;

 

          while((ch=fis.read())!=-1){

 

             System.out.println((char)ch);

 

          }

 

          fis.close();

 

       }

 

       public static void writeFile()throws IOException{  //將數據寫入到文件

 

          FileOutputStream fos = new FileOutputStream("fos.txt");  

 

          fos.write("abcde".getBytes());

 

          fos.close();  

 

       }

 

    }

 

 

 

 

 

  (2)拷貝圖片 

 

    思路:

 

      a.用字節讀取流對象和圖片關聯。

 

      b.用字節寫入流對象建立一個圖片文件。用於存儲獲取到的圖片數據。

 

      c.經過循環讀寫,完成數據的存儲。

 

      d.關閉資源。

 

 

 

    示例Demo:

 

    class  CopyPic

 

    {

 

       public static void main(String[] args){

 

          FileOutputStream fos = null;

 

          FileInputStream fis = null;

 

          try{

 

             fos = new FileOutputStream("c:\\2.bmp");

 

             fis = new FileInputStream("c:\\1.bmp");

 

             byte[] buf = new byte[1024];

 

             int len = 0;

 

             while((len=fis.read(buf))!=-1){

 

              fos.write(buf,0,len);

 

             }

 

          }catch (IOException e){

 

             throw new RuntimeException("複製文件失敗");

 

          }finally{

 

             try{

 

              if(fis!=null)

 

                 fis.close();

 

             }catch (IOException e){

 

              throw new RuntimeException("讀取關閉失敗");

 

             }

 

 

 

             try{

 

              if(fos!=null)

 

                 fos.close();

 

             }catch (IOException e){

 

              throw new RuntimeException("寫入關閉失敗");

 

             }

 

          }

 

       }

 

    }

 

 

 

 

 


 

 

 

 

 

 

 

十、字節流的緩衝區: BufferedOutputStream / BufferedInputStream

 

    字節流的緩衝區一樣是提升了字節流的讀寫效率。 下面就以一個Demo來介紹一下。

 

 

 

  (1)複製mp3:演示緩衝區使用流程

 

    示例Demo:

 

    class  CopyMp3

 

    {

 

       public static void main(String[] args) throws IOException{

 

          long start = System.currentTimeMillis();

 

          copy_2();

 

          long end = System.currentTimeMillis();

 

          System.out.println((end-start)+"毫秒");

 

       }

 

       public static void copy_2()throws IOException

 

       {

 

          MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));

 

          BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));

 

 

 

          int by = 0;

 

          //System.out.println("第一個字節:"+bufis.myRead());

 

          while((by=bufis.myRead())!=-1){

 

             bufos.write(by);

 

          }

 

          bufos.close();

 

          bufis.myClose();

 

       }

 

       //經過字節流的緩衝區完成複製。

 

       public static void copy_1()throws IOException{

 

          BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));

 

          BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));

 

 

 

          int by = 0;

 

          while((by=bufis.read())!=-1){

 

             bufos.write(by);

 

          }

 

          bufos.close();

 

          bufis.close();     

 

       }

 

    }

 

 

 

  (2)自定義字節流的緩衝區-- 探尋read()和write()的特色

 

    示例Demo:

 

      class MyBufferedInputStream

 

      {

 

         private InputStream in;

 

         private byte[] buf = new byte[1024*4];     

 

         private int pos = 0,count = 0;

 

 

 

         MyBufferedInputStream(InputStream in){

 

            this.in = in;

 

         }

 

         //一次讀一個字節,從緩衝區(字節數組)獲取。

 

         public int myRead()throws IOException{

 

            //經過in對象讀取硬盤上數據,並存儲buf中。

 

            if(count==0){

 

               count = in.read(buf);

 

               if(count<0)

 

                return -1;

 

               pos = 0;

 

               byte b = buf[pos];

 

               count--;

 

               pos++;

 

               return b&255;

 

            }else if(count>0){

 

               byte b = buf[pos];

 

               count--;

 

               pos++;

 

               return b&0xff;

 

            }

 

            return -1;

 

         }

 

         public void myClose()throws IOException{

 

            in.close();

 

         }

 

      }

 

 

 

      下面咱們來分析一下:字節流的讀一個字節的read方法爲何返回值類型不是byte,而是int

 

      11111111-111111110000000000101001001010100101010010101001010  //返回的一串二進制代碼的前8位有多是8個1;

 

 

 

      byte: -1  --->  int : -1;

 

      00000000 00000000 00000000 11111111  255

 

      11111111 11111111 11111111 11111111    //此處是爲了與咱們的校驗值 -1(int) 進行比對,進行自動補位而類型提高。

 

 

 

      11111111  -->提高了一個int類型 那不仍是-1嗎?是-1的緣由是由於在8個1前面補的是1致使的。

 

      那麼我只要在前面補0,便可以保留原字節數據不變,又能夠避免-1的出現。

 

      怎麼補0呢?

 

       11111111 11111111 11111111 11111111                        

 

      &00000000 00000000 00000000 11111111 

 

      ------------------------------------

 

       00000000 00000000 00000000 11111111 

 

      0000-0001

 

      1111-1110

 

      000000001

 

      1111-1111  -1

 

 

 

      結論:      。

 

      由於有可能會讀到連續8個二進制1的狀況,8個二進制1對應的十進制是-1.

 

      那麼就會數據尚未讀完,就結束的狀況。由於咱們判斷讀取結束是經過結尾標記-1來肯定的。

 

      因此,爲了不這種狀況將讀到的字節進行int類型的提高。並在保留原字節數據的狀況前面了補了24個0,變成了int類型的數值。       

 

      而在寫入數據時,只寫該int類型數據的最低8位。

 

      注:這兩種操做都被封裝:

 

          「返回數據時自動補位24個0」 ———— 封裝在read()方法裏面;

 

          「寫入數據時只寫該int類型數據的最低8位」 ———— 封裝在write()方法裏面。

 

 

 

 

 


 

 

 

 

 

十一、讀取鍵盤錄入: System.in

 

  java.lang.System類中給咱們提供了兩個對象。

 

    System.out --  InputStream:對應的是標準輸出設備,控制檯。

 

    System.in  --  PrintStream:對應的標準輸入設備:鍵盤。

 

  咱們根據其所屬的數據類型,就能夠看成一種輸入流 或是 輸出流 ,就能夠進行鍵盤的讀取操做與控制檯的輸出。

 

 

 

  示例Demo:

 

  //需求:經過鍵盤錄入數據,當錄入一行數據後,就將該行數據進行打印,若是錄入的數據是over,那麼中止錄入。

 

  class  ReadIn

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        InputStream in = System.in;

 

        StringBuilder sb = new StringBuilder();

 

        while(true){

 

           int ch = in.read();

 

           if(ch=='\r')

 

            continue;

 

           if(ch=='\n'){

 

            String s = sb.toString();

 

            if("over".equals(s))

 

               break;

 

            System.out.println(s.toUpperCase());

 

            sb.delete(0,sb.length());

 

           }else

 

            sb.append((char)ch);

 

        }

 

     }

 

  }

 

 

 

 

 


 

 

 

 

 

十二、讀取/寫入 轉換流:InputStreamReader與OutputStreamWriter

 

    轉換流:InputStreamReader , OutputStreamWriter 

 

    轉換流的由來 

 

        a.字符流與字節流之間的橋樑 

 

        b.方便了字符流與字節流之間的操做 

 

    轉換流的應用 

 

        字節流中的數據都是字符時,轉成字符流操做更高效。 

 

    轉換流的使用之一:做爲字符和字節之間的橋樑,一般涉及到字符編碼轉換時,須要用到轉換流。

 

 

 

  (1)標準輸入輸出

 

    示例Demo1:

 

    class  TransStreamDemo

 

    {

 

       public static void main(String[] args) throws IOException

 

       {

 

          //獲取鍵盤錄入對象。

 

          //InputStream in = System.in;

 

          //將字節流對象轉成字符流對象,使用轉換流。InputStreamReader

 

          //InputStreamReader isr = new InputStreamReader(in);

 

          //爲了提升效率,將字符串進行緩衝區技術高效操做。使用BufferedReader

 

          //BufferedReader bufr = new BufferedReader(isr);

 

 

 

          //鍵盤錄入的最多見寫法。

 

          BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

 

 

 

        //  OutputStream out = System.out;

 

        //  OutputStreamWriter osw = new OutputStreamWriter(out);

 

        //  BufferedWriter bufw = new BufferedWriter(osw);

 

          BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

 

          String line = null;

 

          while((line=bufr.readLine())!=null)

 

          {

 

             if("over".equals(line))

 

              break;

 

             bufw.write(line.toUpperCase());

 

             bufw.newLine();

 

             bufw.flush();

 

          }

 

          bufr.close();

 

       }

 

    } 

 

 

 

 

 

  (2)改變標準的輸入輸出設備

 

    示例Demo1:

 

    //System.setIn(InputStream in);   --- 改變標準的輸入設備

 

    //System.setOut(PrintStream out); --- 改變標準的輸出設備

 

    class  TransStreamDemo2

 

    {

 

       public static void main(String[] args) throws IOException

 

       {

 

          //現將標準的輸入和輸出設備都換成文件。

 

          System.setIn(new FileInputStream("PersonDemo.java"));

 

          System.setOut(new PrintStream("zzz.txt"));

 

          //鍵盤的最多見寫法。

 

          BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));  

 

          BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

 

          String line = null;

 

          while((line=bufr.readLine())!=null)

 

          {

 

             if("over".equals(line))

 

              break;

 

             bufw.write(line.toUpperCase());

 

             bufw.newLine();

 

             bufw.flush();

 

          }

 

          bufr.close();

 

       }

 

    }

 

 

 

 

 

 

 


 

 

 

 

 

1三、衆多IO流對象的選用規律

 

  經過四個步驟來確認完成。

 

  a.明確源和目的。

 

       源:輸入流。InputStream   Reader

 

     目的:輸出流。OutputStream  Writer。

 

  b.操做的數據是不是純文本。

 

     是:字符流。

 

     不是:字節流。

 

  c.明確設備:當體系明確後,再明確要使用哪一個具體的對象。

 

      源設備:內存,硬盤,鍵盤。

 

    目的設備:內存,硬盤,控制檯。

 

  d.是否須要提升效率:

 

    選擇使用 :BufferedReader  和  BufferedWriter   

 

 

 

  Demo1需求:複製文件 -- 將一個文本文件中數據存儲到另外一個文件中。

 

   關於源的分析

 

     a.源:由於是源,因此使用讀取流。InputStream Reader 

 

     b.是否是操做文本文件。

 

       是!這時就能夠選擇Reader

 

       這樣體系就明確了。接下來明確要使用該體系中的哪一個對象。

 

     c.明確設備:硬盤。上一個文件。

 

       Reader體系中能夠操做文件的對象是 FileReader

 

     d.是否須要提升效率:是!。加入Reader體系中緩衝區 BufferedReader.

 

       FileReader fr = new FileReader("a.txt");

 

       BufferedReader bufr = new BufferedReader(fr);

 

   關於目的分析

 

     a.目的:OutputStream Writer

 

     b.是不是純文本。

 

      是!Writer。

 

     c.設備:硬盤,一個文件。

 

      Writer體系中能夠操做文件的對象FileWriter。

 

     d.是否須要提升效率:是!。加入Writer體系中緩衝區 BufferedWriter 

 

       FileWriter fw = new FileWriter("b.txt");

 

       BufferedWriter bufw = new BufferedWriter(fw);

 

 

 

  Demo2需求:將鍵盤錄入的數據保存到一個文件中。

 

  關於源的分析

 

     a.源:InputStream Reader

 

     b.是否是純文本?是!Reader 

 

     c.設備:鍵盤。對應的對象是System.in.

 

       不是選擇Reader嗎?System.in對應的不是字節流嗎?

 

       爲了操做鍵盤的文本數據方便。轉成字符流按照字符串操做是最方便的。

 

       因此既然明確了Reader,那麼就將System.in轉換成Reader。

 

       用了Reader體系中轉換流,InputStreamReader

 

        InputStreamReader isr = new InputStreamReader(System.in);

 

     d.須要提升效率嗎?須要!BufferedReader

 

     BufferedReader bufr = new BufferedReader(isr);

 

  關於目的分析

 

     a.目的:OutputStream  Writer

 

     b.是不是存文本?是!Writer。

 

     c.設備:硬盤。一個文件。使用 FileWriter。

 

      FileWriter fw = new FileWriter("c.txt");

 

     d.須要提升效率嗎?須要。

 

       BufferedWriter bufw = new BufferedWriter(fw); 

 

 

 

  Demo3需求:擴展一下,想要把錄入的數據按照指定的編碼表(utf-8),將數據存到文件中。

 

  關於目的分析 

 

     a.目的:OutputStream  Writer

 

     b.是不是存文本?是!Writer。

 

     c.設備:硬盤。一個文件。使用 FileWriter。

 

       但是FileWriter是使用的默認編碼表:GBK,而在存儲時,須要加入指定編碼表utf-8,但指定的編碼表只有轉換流能夠指定。

 

       因此要使用的對象是OutputStreamWriter。該轉換流對象要接收一個字節輸出流,那麼能夠操做文件的字節輸出流是:FileOutputStream

 

       OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

 

     d.須要高效嗎?須要。

 

      BufferedWriter bufw = new BufferedWriter(osw);

 

  因此記住:轉換流何時使用:做爲字符和字節之間的橋樑。一般涉及到字符編碼轉換時,須要用到轉換流。

 

 

 

 

 

 

 


 

 

 

 

 

1四、保存「異常信息」到日誌文件

 

  注:本例僅做思路參考,開發時 大多使用log4j 這個開源的插件。

 

 

 

  示例Demo1:保存異常信息

 

  class  ExceptionInfo

 

  {

 

     public static void main(String[] args)throws IOException 

 

     {

 

        try

 

        {

 

           int[] arr = new int[2];

 

           System.out.println(arr[3]);  //會產生數組角標越界的異常

 

        }

 

        catch (Exception e)

 

        {   

 

           try

 

           {

 

            Date d = new Date();

 

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

            String s = sdf.format(d);

 

            PrintStream ps = new PrintStream("exeception.log");

 

            ps.println(s);

 

            System.setOut(ps);    

 

           }

 

           catch (IOException ex)

 

           {

 

            throw new RuntimeException("日誌文件建立失敗");  //這是給上一層調用人員使用的

 

           }

 

           e.printStackTrace(System.out);  //這是將異常的日誌信息保存到文件中。

 

        }

 

     }

 

  }

 

 

 

  示例Demo2:將系統信息保存到文件中

 

  class  SystemInfo

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        Properties prop = System.getProperties();

 

        //System.out.println(prop);

 

        prop.list(new PrintStream("sysinfo.txt"));

 

     }

 

  }

 

 

 

 

 

 

 


 

 

 

 

 

1五、File對象的建立、刪除、判斷、獲取等功能。

 

  File對象的做用:

 

    a.用來將文件或者文件夾封裝成對象 

 

    b.方便對文件與文件夾的屬性信息進行操做。 

 

    c.File對象能夠做爲參數傳遞給流的構造函數。 

 

 

 

  File類常見方法:

 

    (1)構造方法 

 

      File(File parent, String child) 

 

            根據 parent 抽象路徑名和 child 路徑名字符串建立一個新 File 實例。 

 

      File(String pathname) 

 

            經過將給定路徑名字符串轉換爲抽象路徑名來建立一個新 File 實例。 

 

      File(String parent, String child) 

 

            根據 parent 路徑名字符串和 child 路徑名字符串建立一個新 File 實例。 

 

      File(URI uri) 

 

            經過將給定的 file: URI 轉換爲一個抽象路徑名來建立一個新的 File 實例。 

 

 

 

    (2)建立。

 

       boolean - createNewFile():在指定位置建立文件,若是該文件已經存在,則不建立,返回false。

 

                        和輸出流不同,輸出流對象一創建建立文件。並且文件已經存在,會覆蓋。

 

       boolean - mkdir():建立文件夾。

 

       boolean - mkdirs():建立多級文件夾。

 

 

 

    (3)刪除。

 

       boolean - delete():刪除失敗返回false。若是文件正在被使用,則刪除不了返回false。

 

          void - deleteOnExit();在程序退出時刪除指定文件。

 

 

 

    (4)判斷。

 

       boolean - exists():文件是否存在.

 

       boolean - isFile():測試此抽象路徑名錶示的文件是不是一個標準文件。

 

       boolean - isDirectory();測試此抽象路徑名錶示的文件是不是一個目錄。

 

       boolean - isHidden(); 測試此抽象路徑名指定的文件是不是一個隱藏文件。

 

       boolean - isAbsolute(); 測試此抽象路徑名是否爲絕對路徑名。

 

 

 

    (5)獲取信息。

 

       String - getName(): 返回由此抽象路徑名錶示的文件或目錄的名稱。

 

       String - getPath():將此抽象路徑名轉換爲一個路徑名字符串。

 

       String - getParent():返回此抽象路徑名父目錄的路徑名字符串;若是此路徑名沒有指定父目錄,則返回 null。

 

       String - getAbsolutePath(): 返回此抽象路徑名的絕對路徑名字符串。

 

         long - lastModified(): 返回此抽象路徑名錶示的文件最後一次被修改的時間。

 

         long - length(): 返回由此抽象路徑名錶示的文件的長度。

 

 

 

  示例Demo:

 

  class FileDemo 

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        method_5();

 

     }

 

     public static void method_5()

 

     {

 

        File f1 = new File("c:\\Test.java");

 

        File f2 = new File("d:\\hahah.java");

 

        sop("rename:"+f2.renameTo(f1));

 

     }

 

     public static void method_4()

 

     {

 

        File f = new File("file.txt");

 

        sop("path:"+f.getPath());

 

        sop("abspath:"+f.getAbsolutePath());

 

        sop("parent:"+f.getParent());//該方法返回的是絕對路徑中的父目錄。若是獲取的是相對路徑,返回null。

 

         //若是相對路徑中有上一層目錄那麼該目錄就是返回結果。

 

     }   

 

     public static void method_3()throws IOException

 

     {

 

        File f = new File("d:\\java1223\\day20\\file2.txt");

 

        //f.createNewFile();

 

        //f.mkdir();

 

        //記住在判斷文件對象是不是文件或者目的時,必需要先判斷該文件對象封裝的內容是否存在。

 

        //經過exists判斷。

 

        sop("dir:"+f.isDirectory());

 

        sop("file:"+f.isFile());

 

        sop(f.isAbsolute());

 

     }

 

     public static void method_2()

 

     {

 

        File f = new File("file.txt");

 

        //sop("exists:"+f.exists());

 

        //sop("execute:"+f.canExecute());

 

        //建立文件夾

 

        File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

 

        sop("mkdir:"+dir.mkdirs());

 

     }

 

     public static void method_1()throws IOException

 

     {

 

        File f = new File("file.txt");

 

        //sop("create:"+f.createNewFile());

 

        //sop("delete:"+f.delete());  

 

     }

 

     //建立File對象

 

     public static void consMethod()

 

     {

 

        //將a.txt封裝成file對象。能夠將已有的和爲出現的文件或者文件夾封裝成對象。

 

        File f1 = new File("a.txt");

 

        //

 

        File f2 = new File("c:\\abc","b.txt");

 

        File d = new File("c:\\abc");

 

        File f3 = new File(d,"c.txt");

 

        sop("f1:"+f1);

 

        sop("f2:"+f2);

 

        sop("f3:"+f3);

 

        File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");

 

     }

 

     public static void sop(Object obj)

 

     {

 

        System.out.println(obj);

 

     }

 

  }

 

 

 

 

 


 

 

 

 

 

1六、File對象 ———— 實現文件列表功能經常使用方法

 

  可以實現文件列表的一些方法與接口:

 

    (1)File[] listFiles(): 返回一個抽象路徑名數組,這些路徑名錶示此抽象路徑名錶示的目錄中的文件。 

 

 

 

    (2)String[] listFiles(FilenameFilter filter) 

 

        返回抽象路徑名數組,這些路徑名錶示此抽象路徑名錶示的目錄中知足指定過濾器的文件和目錄。 

 

        FilenameFilter接口的知識

 

        接口:java.io.FilenameFilter :實現此接口的類實例可用於過濾器文件名,

 

        方法:boolean accept(File dir,String name):測試指定文件是否應該包含在某一文件列表中。 

 

            參數:dir - 被找到的文件所在的目錄。

 

                name - 文件的名稱。 

 

            返回:當且僅當該名稱應該包含在文件列表中時返回 true;不然返回 false。

 

 

 

    (3)String[] list():返回一個字符串數組,這些字符串指定此抽象路徑名錶示的目錄中的文件和目錄。 

 

 

 

    (4)static File[] listRoots():列出可用的文件系統根。 

 

 

 

 

 

  示例Demo:

 

  class  FileDemo2

 

  {

 

    // 使用 File[] listFiles()方法

 

     public static void main(String[] args) 

 

     {

 

        File dir = new File("c:\\");

 

        File[] files = dir.listFiles();

 

        for(File f : files)

 

        {

 

           System.out.println(f.getName()+"::"+f.length());

 

        }  

 

     }

 

     // 使用 String[] listFiles(FilenameFilter filter) 方法

 

     public static void listDemo_2()  

 

     {

 

        File dir = new File("d:\\java1223\\day18");

 

        String[] arr = dir.list(new FilenameFilter()

 

        {

 

           public boolean accept(File dir,String name)

 

           {

 

            //System.out.println("dir:"+dir+"....name::"+name);

 

            /*

 

            if(name.endsWith(".bmp"))

 

               return true;

 

            else

 

              return false;

 

            */

 

            return name.endsWith(".bmp");

 

           }

 

        });

 

 

 

        System.out.println("len:"+arr.length);

 

        for(String name : arr)

 

        {

 

           System.out.println(name);

 

        }

 

     }

 

     // 使用 String[] list()方法

 

     public static void listDemo()   

 

     {

 

        File f = new File("c:\\abc.txt");

 

        String[] names = f.list();//調用list方法的file對象必須是封裝了一個目錄。該目錄還必須存在。

 

        for(String name : names)

 

        {

 

           System.out.println(name);

 

        }

 

     }

 

     // 使用static File[] listRoots()方法

 

     public static void listRootsDemo()   

 

     {

 

        File[] files = File.listRoots();

 

        for(File f : files)

 

        {

 

           System.out.println(f);

 

        }

 

     }

 

  }

 

 

 

 

 


 

 

 

1七、File對象 —— 操做 文件列表/目錄

 

  (1)列出目錄下全部內容——遞歸方法(含帶層次展示)

 

    需求分析:列出指定目錄下文件或者文件夾,包含子目錄中的內容,也就是列出指定目錄下全部內容。由於目錄中還有目錄,只要使用同一個列出目錄功能的函數完成便可。在列出過程當中出現的仍是目錄的話,還能夠再次調用本功能。也就是函數自身調用自身。

 

    遞歸算法:這種函數自身調用自身的表現形式,或者編程手法,稱爲遞歸。

 

    遞歸要注意:a.限定條件。

 

          b.要注意遞歸的次數,儘可能避免內存溢出。

 

    示例Demo:

 

    class FileDemo3 

 

    {

 

       public static void main(String[] args) 

 

       {

 

          File dir = new File("d:\\testdir");

 

          showDir(dir,0);

 

 

 

          System.out.println(dir.delete());

 

       }

 

       //根據文件所在層級書寫層標「|--」

 

       public static String getLevel(int level)

 

       {

 

          StringBuilder sb = new StringBuilder();

 

          sb.append("|--");

 

          for(int x=0; x<level; x++)

 

          {

 

             //sb.append("|--");

 

             sb.insert(0,"|  ");

 

          }

 

          return sb.toString();

 

       }

 

      //採用遞歸算法,列出全部 Java文件列表

 

       public static void showDir(File dir,int level)

 

       {

 

 

 

          System.out.println(getLevel(level)+dir.getName());

 

          level++;

 

          File[] files = dir.listFiles();

 

          for(int x=0; x<files.length; x++)

 

          {

 

             if(files[x].isDirectory())

 

              showDir(files[x],level);

 

             else

 

              System.out.println(getLevel(level)+files[x]);

 

          }

 

       }      

 

    }

 

 

 

  (2)刪除帶內容的目錄

 

    刪除原理:在window中,刪除目錄從裏面往外刪除的。既然是從裏往外刪除,就須要用到遞歸。  

 

    示例Demo:

 

    class  RemoveDir

 

    {

 

       public static void main(String[] args) 

 

       {  

 

          File dir = new File("d:\\testdir");

 

          removeDir(dir);

 

       }

 

       public static void removeDir(File dir)

 

       {

 

          File[] files = dir.listFiles();  

 

          for(int x=0; x<files.length; x++)

 

          {

 

             if(files[x].isDirectory())

 

              removeDir(files[x]);

 

             else

 

              System.out.println(files[x].toString()+":-file-:"+files[x].delete());

 

          }

 

          System.out.println(dir+"::dir::"+dir.delete());

 

       }

 

    } 

 

 

 

  (3)建立展示多層級的Java文件列表並輸出到文件

 

    需求:將一個指定目錄下的java文件的絕對路徑,存儲到一個文本文件中,創建一個java文件列表文件。

 

    思路:

 

      a.對指定的目錄進行遞歸。

 

      b.獲取遞歸過程因此的java文件的路徑。

 

      c.將這些路徑存儲到集合中。

 

      d.將集合中的數據寫入到一個文件中。

 

    示例Demo:

 

    class  JavaFileList

 

    {

 

       public static void main(String[] args) throws IOException

 

       {  

 

          File dir = new File("d:\\java1223");

 

          List<File> list = new ArrayList<File>();

 

          fileToList(dir,list);

 

          //System.out.println(list.size());

 

          File file = new File(dir,"javalist.txt");

 

          writeToFile(list,file.toString());

 

       }

 

       public static void fileToList(File dir,List<File> list)

 

       {

 

          File[] files = dir.listFiles();

 

          for(File file : files)

 

          {

 

             if(file.isDirectory())

 

              fileToList(file,list);

 

             else

 

             {

 

              if(file.getName().endsWith(".java"))

 

                 list.add(file);

 

             }

 

          }

 

       }

 

       public static void writeToFile(List<File> list,String javaListFile)throws IOException

 

       {

 

          BufferedWriter bufw =  null;

 

          try

 

          {

 

             bufw = new BufferedWriter(new FileWriter(javaListFile));   

 

             for(File f : list)

 

             {

 

              String path = f.getAbsolutePath();

 

              bufw.write(path);

 

              bufw.newLine();

 

              bufw.flush();

 

             }

 

          }

 

          catch (IOException e)

 

          {

 

           throw e;

 

          }

 

          finally

 

          {

 

             try

 

             {

 

              if(bufw!=null)

 

                 bufw.close();

 

             }

 

             catch (IOException e)

 

             {

 

              throw e;

 

             }

 

          }

 

       }

 

    }

 

 

 

 

 


 

 

 

1八、Properties  存取配置文件

 

  Properties是hashtable的子類,也就是說它具有map集合的特色,並且它裏面存儲的鍵值對都是字符串,是集合中與IO技術相結合的集合容器。

 

  該對象的特色:能夠用於鍵值對形式的配置文件。

 

  那麼在加載數據時,須要數據有固定格式:鍵=值。

 

 

 

  示例Demo:

 

  class PropertiesDemo 

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        //method_1();

 

        loadDemo();

 

     }

 

 

 

     //這是 讀取 properties 類型配置文件 最標準的 流程,能夠直接在開發中應用。

 

     public static void loadDemo()throws IOException

 

     {

 

        Properties prop = new Properties();

 

        FileInputStream fis = new FileInputStream("info.txt");

 

        //將流中的數據加載進集合。

 

        prop.load(fis);

 

        //取出屬性值的操做

 

        String value = prop.getProperty("lisi");

 

        //該從配置文件中讀取的「lisi」 的 屬性值,就能夠被咱們使用了。

 

 

 

        //給屬性賦值的操做。

 

        prop.setProperty("wangwu","39");

 

        //將修改過屬性值的集合 從新寫回配置文件中:更新

 

        FileOutputStream fos = new FileOutputStream("info.txt");

 

        prop.store(fos,"haha");

 

        // System.out.println(prop);

 

        prop.list(System.out);

 

        fos.close();

 

        fis.close();      

 

    }

 

 

 

 

 

     //下面演示,自定義方法:將流中的數據存儲到集合中。

 

     //想要將info.txt中鍵值數據存到集合中進行操做。

 

     /*

 

      1,用一個流和info.txt文件關聯。

 

      2,讀取一行數據,將該行數據用"="進行切割。

 

      3,等號左邊做爲鍵,右邊做爲值。存入到Properties集合中便可。

 

     */

 

     public static void method_1()throws IOException

 

     {

 

        BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));

 

        String line = null;

 

        Properties prop = new Properties();

 

        while((line=bufr.readLine())!=null)

 

        {

 

           String[] arr = line.split("=");

 

           ///System.out.println(arr[0]+"...."+arr[1]);

 

           prop.setProperty(arr[0],arr[1]);

 

        }

 

        bufr.close();

 

        System.out.println(prop);

 

     }

 

    // 設置和獲取元素。

 

     public static void setAndGet()

 

     {

 

        Properties prop = new Properties();

 

        prop.setProperty("zhangsan","30");

 

        prop.setProperty("lisi","39");

 

      //  System.out.println(prop);

 

        String value = prop.getProperty("lisi");

 

        //System.out.println(value);   

 

        prop.setProperty("lisi",89+"");

 

        Set<String> names = prop.stringPropertyNames();

 

        for(String s : names)

 

        {

 

           System.out.println(s+":"+prop.getProperty(s));

 

        }

 

     } 

 

  }

 

 

 

 

 


 

 

 

1九、PrintStream 以及 PrintWriter

 

  打印流:該流提供了打印方法,能夠將各類數據類型的數據都原樣打印。

 

  PrintStream - 字節打印流:

 

    構造函數能夠接收的參數類型:

 

      a.file對象。File  --------- PrintStream(File file) 

 

      b.字符串路徑。String  ----- PrintStream(String fileName) 

 

      c.字節輸出流。OutputStream  PrintStream(OutputStream out) 

 

 

 

  PrintWriter - 字符打印流

 

    構造函數能夠接收的參數類型:

 

      a.file對象。File  ----------- PrintWriter(File file) 

 

      b.字符串路徑。String  ------- PrintWriter(String fileName) 

 

      c.字節輸出流。OutputStream -- PrintWriter(OutputStream out) 

 

      d.字符輸出流,Writer。  ----- PrintWriter(Writer out) 

 

  【備註:在構造函數中能夠 添加 true/false, 以表明是否須要自動刷新。】

 

  示例Demo:

 

  class  PrintStreamDemo

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        BufferedReader bufr = 

 

           new BufferedReader(new InputStreamReader(System.in));

 

        PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

 

        String line = null;              //自動刷新

 

        while((line=bufr.readLine())!=null)

 

        {

 

           if("over".equals(line))

 

          break;

 

           out.println(line.toUpperCase());  //自帶平臺適應的行分隔符(等同於換行符)

 

           //out.flush();

 

        }

 

        out.close();

 

        bufr.close();

 

     } 

 

  }

 

 

 

 

 

 

 


 

 

 

 

 

20、文件的 切割操做

 

  示例Demo:

 

  @Test

 

   public static void splitFile()throws IOException

 

   {

 

      FileInputStream fis =  new FileInputStream("c:\\1.bmp");

 

      FileOutputStream fos = null;

 

      byte[] buf = new byte[1024*1024];  //切割後每份的大小。

 

      int len = 0;

 

      int count = 1;

 

      while((len=fis.read(buf))!=-1)

 

      {

 

         fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");

 

         fos.write(buf,0,len);

 

         fos.close();

 

      }  

 

      fis.close();  

 

   }

 

 

 

 

 


 

 

 

2一、文件的合併操做 -----  SequenceInputStream 合併文件

 

  SequenceInputStream:表示其餘輸入流的邏輯串聯。它從輸入流的有序集合開始,並從第一個輸入流開始讀取,直到到達文件末尾,接着從第二個輸入流讀取,依次類推,直到到達包含的最後一個輸入流的文件末尾爲止。 

 

  構造方法:SequenceInputStream(Enumeration<? extends InputStream> e) 

 

    經過記住參數來初始化新建立的 SequenceInputStream,該參數必須是生成運行時類型爲 InputStream 對象的 Enumeration 型參數。

 

 

 

  SequenceInputStream 的兩種裝載方式:

 

      a. Vector方式:操做方便,可是效能遠低於ArrayList。

 

      b. ArrayList方式:操做稍顯麻煩,可是ArrayList的性能要比Vector高不少。

 

 

 

  示例Demo:  

 

  //第一種 SequenceInputStream 的裝載方式 ————  Vector

 

  @Test

 

   public static void merge1() throws IOException

 

   {

 

      Vector<FileInputStream> v = new Vector<FileInputStream>();  

 

       v.add(new FileInputStream("c:\\1.txt"));

 

       v.add(new FileInputStream("c:\\2.txt"));

 

       v.add(new FileInputStream("c:\\3.txt"));

 

      Enumeration<FileInputStream> en = v.elements();//僅Vector結合對象能獲得Enumeration類型。

 

      SequenceInputStream sis = new SequenceInputStream(en);  //將多個文本的輸入流 組裝到SequenceInputStream中

 

      FileOutputStream fos = new FileOutputStream("c:\\4.txt");

 

      byte[] buf = new byte[1024];

 

      int len =0;

 

      while((len=sis.read(buf))!=-1)  //把 SequenceInputStream 看成一個 普通輸入流 讀取數據。

 

      {

 

         fos.write(buf,0,len);

 

      }

 

      fos.close();

 

      sis.close();

 

   }

 

 

 

  //第二種 SequenceInputStream 的裝載方式  ————  ArrayList

 

  @Test

 

   public static void merge2()throws IOException

 

   {

 

      ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();

 

      for(int x=1; x<=3; x++)

 

      {

 

         al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));

 

      }

 

      final Iterator<FileInputStream> it = al.iterator();

 

 

 

     //將 it 裝載入 Enumeration 裏面

 

      Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()

 

      {

 

         public boolean hasMoreElements()

 

         {

 

          return it.hasNext();

 

         }

 

         public FileInputStream nextElement()

 

         {

 

          return it.next();

 

         }

 

      };

 

      //上面的文件合併功能實現方式 若稍顯麻煩(可是ArrayList的性能要比Vector高不少),

 

      // 能夠參見「#SquenceInputSteam 合併文件」 中的演示。

 

      SequenceInputStream sis = new SequenceInputStream(en);

 

      FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");

 

      byte[] buf = new byte[1024];

 

      int len = 0;

 

      while((len=sis.read(buf))!=-1)

 

      {

 

       fos.write(buf,0,len);

 

      }

 

      fos.close();

 

      sis.close();

 

   }

 

 

 

 

 

 

 


 

 

 

 

 

2二、對象的序列化:ObjectOutputStream 和反序列化:ObjectInputStream    

 

  ObjectOutputStream

 

    做用:可將對象寫入流中(對象類需實現Serializable接口);

 

        也可將 Java 對象的基本數據類型和圖形寫入 OutputStream。    

 

  ObjectInputStream 對之前使用 ObjectOutputStream 寫入的基本數據和對象進行反序列化。 

 

 

 

  示例Demo:

 

  class ObjectStreamDemo 

 

  {

 

     public static void main(String[] args) throws Exception

 

     {

 

        //writeObj();

 

        readObj();

 

     }

 

     public static void readObj()throws Exception

 

     {

 

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

 

        Person p = (Person)ois.readObject();  //該Person類必須是實現了Serializable 接口

 

        System.out.println(p);

 

        ois.close();

 

     }

 

     public static void writeObj()throws IOException

 

     {

 

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));

 

        oos.writeObject(new Person("lisi0",399,"kr"));  //將對象保存到硬盤文件"obj.txt" 中。

 

        oos.close();      //該Person類必須是實現了Serializable 接口

 

     }

 

  }

 

 

 

 

 


 

 

 

 

 

2三、RandomAccessFile 隨機讀寫訪問文件

 

  RandomAccessFile:該類不是算是IO體系中子類,而是直接繼承自Object,可是它是IO包中成員,由於它具有讀和寫功能。其內部封裝了一個數組,並且經過指針對數組的元素進行操做。

 

  咱們能夠經過getFilePointer()獲取指針位置,同時能夠經過seek()改變指針的位置,其實完成讀寫的原理就是內部封裝了字節輸入流和輸出流。

 

  【備註:可實現多線程併發讀寫同一文件:如迅雷技術。】

 

  構造函數:

 

    RandomAccessFile(File file, String mode) 

 

          建立從中讀取和向其中寫入(可選)的隨機訪問文件流,該文件由 File 參數指定。 

 

    RandomAccessFile(String name, String mode) 

 

          建立從中讀取和向其中寫入(可選)的隨機訪問文件流,該文件具備指定名稱。 

 

      mode 參數指定用以打開文件的訪問模式。容許的值及其含意爲:

 

        值      含意       

 

        "r"     以只讀方式打開。調用結果對象的任何 write 方法都將致使拋出 IOException。  

 

        "rw"    打開以便讀取和寫入。若是該文件尚不存在,則嘗試建立該文件。  

 

 

 

  經過構造函數能夠看出,該類只能操做文件,並且操做文件還有模式:只讀r,讀寫rw等。

 

    若是模式爲只讀 r。不會建立文件。會去讀取一個已存在文件,若是該文件不存在,則會出現異常。

 

    若是模式rw。操做的文件不存在,會自動建立。若是存則不會覆蓋。

 

 

 

  示例Demo:

 

  class RandomAccessFileDemo 

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        //writeFile_2();

 

        //readFile();

 

        //System.out.println(Integer.toBinaryString(258));

 

     }

 

     //測試打開一個只讀的RandomAccessFile對象

 

     public static void readFile()throws IOException

 

     {

 

        RandomAccessFile raf = new RandomAccessFile("ran.txt","r");  

 

        //調整對象中指針。

 

        //raf.seek(8*1);    //注:該方法不但能向後跳,還能再跳回來。

 

        //跳過指定的字節數

 

        raf.skipBytes(8);    //注:該方法僅能向後跳,不能再跳回來。

 

        byte[] buf = new byte[4];

 

        raf.read(buf);

 

        String name = new String(buf);

 

        int age = raf.readInt();

 

        System.out.println("name="+name);

 

        System.out.println("age="+age);

 

        raf.close();

 

 

 

     }

 

     //測試打開一個 可讀也可寫的RandomAccessFile對象

 

     public static void writeFile_2()throws IOException

 

     {

 

        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");

 

        raf.seek(8*0);  //讀取數據

 

        raf.write("週期".getBytes());  //寫入數據

 

        raf.writeInt(103);

 

        raf.close();

 

     }

 

    //測試寫入數據 

 

     public static void writeFile()throws IOException

 

     {

 

        RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");

 

        raf.write("李四".getBytes());    //寫入字節數據 

 

        raf.writeInt(97);    //寫入整型數據 

 

        raf.write("王五".getBytes());

 

        raf.writeInt(99);

 

        raf.close();

 

     }

 

  }

 

 

 

 

 


 

 

 

2四、操做基本數據類型 DataInputStream與DataOutputStream

 

  DataInputStream與DataOutputStream 能夠用於操做基本數據類型的數據的流對象,減小字節位數 轉換的麻煩。

 

 

 

  示例Demo:

 

  class DataStreamDemo 

 

  {

 

     public static void main(String[] args) throws IOException

 

     {

 

        //writeData();

 

        //readData();

 

        //writeUTFDemo();

 

      //  OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

 

      //  osw.write("你好");

 

      //  osw.close();

 

      //  readUTFDemo();

 

     }

 

     public static void readUTFDemo()throws IOException

 

     {

 

        DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));

 

        String s = dis.readUTF();  //讀入一個已使用 UTF-8 修改版格式編碼的字符串。

 

        System.out.println(s);

 

        dis.close();

 

     }

 

     public static void writeUTFDemo()throws IOException

 

     {

 

        DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));

 

        dos.writeUTF("你好");//將表示長度信息的兩個字節寫入輸出流,後跟字符串 s 中每一個字符的 UTF-8 修改版表示形式。

 

        dos.close();

 

     }

 

     public static void readData()throws IOException

 

     {

 

        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));

 

        int num = dis.readInt();      // 讀取 int 類型的數據

 

        boolean b = dis.readBoolean();  // 讀取布爾類型的數據

 

        double d = dis.readDouble();    // 讀取雙精度類型的數據

 

        System.out.println("num="+num);

 

        System.out.println("b="+b);

 

        System.out.println("d="+d);

 

        dis.close();

 

     }

 

     public static void writeData()throws IOException

 

     {

 

        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

 

        dos.writeInt(234);  //寫入 int 類型的數據

 

        dos.writeBoolean(true);//寫入布爾類型的數據

 

        dos.writeDouble(9887.543);// 寫入雙精度類型的數據

 

        dos.close();

 

        ObjectOutputStream oos = null;

 

        oos.writeObject(new O());  //寫入對象數據

 

     }

 

  }

 

 

 

 

 

 

 


 

 

 

 

 

2五、ByteArrayStream 操做字節數組的流對象。

 

  用於操做字節數組的流對象。

 

    ByteArrayInputStream : 在構造的時候,須要接收數據源,並且數據源是一個字節數組。

 

    ByteArrayOutputStream: 在構造的時候,不用定義數據目的,由於該對象中已經內部封裝了可變長度的字節數組。這就是數據目的地。

 

  由於這兩個流對象都操做的數組,並無使用系統資源,因此不用進行close關閉。

 

  在流操做規律講解時:

 

    源設備,

 

      鍵盤 System.in,硬盤 FileStream,內存 ArrayStream。

 

    目的設備:

 

      控制檯 System.out,硬盤FileStream,內存 ArrayStream。

 

    用流的讀寫思想來操做數據。

 

 

 

  示例Demo:

 

  class ByteArrayStream 

 

  {

 

     public static void main(String[] args) 

 

     {

 

        //數據源。

 

        ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());

 

        //數據目的

 

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

 

        int by = 0;

 

        while((by=bis.read())!=-1)

 

        {

 

           bos.write(by);

 

        }

 

        System.out.println(bos.size());

 

        System.out.println(bos.toString());

 

       // bos.writeTo(new FileOutputStream("a.txt"));

 

     }

 

  }

 

 

 

 

 


 

 

 

 

 

2六、字符的編碼和解碼

 

  編碼:字符串變成字節數組:String-->byte[];  str.getBytes(charsetName);

 

  解碼:字節數組變成字符串:byte[] -->String: new String(byte[],charsetName);

 

  (1)編碼 和 解碼 的練習

 

    示例Demo:

 

    class  EncodeDemo

 

    {

 

       public static void main(String[] args)throws Exception 

 

       {

 

          String s = "哈哈";

 

          byte[] b1 = s.getBytes("GBK");

 

          System.out.println(Arrays.toString(b1));

 

          String s1 = new String(b1,"utf-8");

 

          System.out.println("s1="+s1);

 

          //對s1進行iso8859-1編碼。

 

          byte[] b2 = s1.getBytes("utf-8");

 

          System.out.println(Arrays.toString(b2));

 

          String s2 = new String(b2,"gbk");

 

          System.out.println("s2="+s2);

 

       }

 

    }

 

 

 

  (2)轉換流的字符編碼

 

    示例Demo:

 

    class EncodeStream 

 

    {

 

       public static void main(String[] args) throws IOException 

 

       {

 

           //writeText();

 

           readText();

 

       }

 

       public static void readText()throws IOException 

 

       {

 

          InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");

 

          char[] buf = new char[10];

 

          int len = isr.read(buf);

 

          String str = new String(buf,0,len);

 

          System.out.println(str);

 

          isr.close();

 

       }

 

       public static void writeText()throws IOException 

 

       {

 

          OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");

 

          osw.write("你好");

 

          osw.close();

 

       }

 

    }

 

 

 

 

 

附圖片: 編碼1.jpg  和 編碼2.jpg

 

 

 

編碼1.jpg  

 



 

 

 

 

編碼2.jpg 

 

IO流  學習筆記

 


 

相關文章
相關標籤/搜索