黑馬程序員-Java-IO流篇《六》

                   ——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——

1. java.io.File類

    File類代表系統文件(文件和目錄),磁盤上的文件和目錄在Java程序中是用File類的實例來表示。

    常用的構造方法:File (String pathname);File(File parent, String child) ;File(String parent,String child)

                           以pathname爲路徑創建File對象,如果pathname是相對路徑,則是相對於Java的

                           系統屬性user.dir中的路徑(即當前字節碼運行的目錄)。

    File類的一個常用屬性:public static final String separator

                                   存儲了當前系統的路徑分隔符。在Unix中該字段值爲“/”,在Windows中爲“\\”.

                                   作用:實現了跨平臺性,用這個表示分隔符就不用擔心,不同系統的表示方式。

2.File類的常用方法

       File的讀寫運屬性:

       boolean   canExecute() ;//測試應用程序是否能夠執行該File文件。

       boolean   canRead(); //是否可讀取。

       boolean   canWrite(); //是否可以修改

       判斷:

       boolean   equals(Object obj); //測試此抽象路徑名是否與給定對象相等

       boolean    exists(); //測試此文件或目錄是否已存在

       boolean    isDirectory() ;//判斷是否是一個目錄

       boolean    isFile (); //判斷是否是一個文件

       boolean    isHidden(); //判斷是否是一個隱藏文件

       獲取:

       long     length(); //返回文件的長度,以字節爲單位

       long     lastModified(); //返回文件最後一次被修改的時間

       File      getAbsoluteFile() ;//返回此的抽象路徑名的絕對路徑名形式。

       String  getAbsolutePath(); //返回此抽象路徑名的絕對路徑名字符串

       String  getName() ;//得到該文件名或該抽象路徑的最後一個目錄的名稱。

       String  getParent();// 返回父目錄的路徑字符串,如果此路徑沒有指定父目錄,則返回null

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

       對文件的操作:

       boolean  createNewFile(); //當不存在時,創建一個新的空文件

       boolean  delete(); //刪除此文件,如果是目錄,必須是空才能刪除,且刪除的是最底的目錄

       boolean  mkdir() ;//創建此抽象路徑名指定的目錄

       boolean  mkdirs(); //創建此目錄,包括所有必需但不存在的父目錄。

       boolean  renameTo( File  dest);// 重新命名此文件

       瀏覽目錄中的文件和子目錄

      String [] list() ;//返回此目錄的文件名和目錄名的數組

      File[] listFiles();//返回此目錄中的文件和目錄的File實例數組。

      File[] listFiles(FilenameFilter filter) ;//返回此目錄中滿足指定過濾器的文件和目錄

         java.io.FilenameFilter接口:實現該接口的類實例可以用於過濾文件名。

3. File創建的步驟

    1.文件或目錄。

    2.文件—a.先判斷,f.exists(); b.創建 ,f.createNewFile(); //只能在已存在的路徑下創建該文件。

       目錄—a.先判斷,f.exists(); b.創建—    f.mkdir();//路徑上僅最後一個目錄是不存在時

                                                      |—  f.mkdirs();//路徑上後面有多個目錄不存在時

 4.Java I/O 原理

    數據流(Stream) 是指數據通信的通道。

    Java程序對數據的輸入,輸出操作是以“流”的方式進行的。JDK中提供了各式的“流”類來獲取不同種類的數據

5.流的分類

   5.1 流的方向:

  • 輸入流:程序可以從中讀取數據的流

  • 輸出流:程序可以向其中寫入數據的流    

   5.1 數據傳輸單位

  • 字節流:以字節爲單位傳輸數據的流。

  • 字符流:以字符爲單位傳輸數據的流。

   5.3 功能

  • 節點流:用於直接操作目標設備的流

  • 處理流:是對一個已存在的流的連接和封裝,通過對數據的處理爲程序提供更爲強大,靈活的讀寫功能。

6.流的種類

     所有的流類都位於java.io包中,都分別繼承自以下四種抽象流類

     輸入流  ------  InputStream(字節流)    ------  Reader(字符流)

     輸出流  ------  OutputStream(字節流)  ------  Writer(字符流)

 7.InputStream 抽象類

   繼承InputStream的流都是用於向程序中輸入數據的,且數據的單位是一個字節。

   InputStream  |---- FileInputStream (節點流)            |----  SequenceInputStream (處理流)

                       |---- PipedInputstream                      |----  ObjectInputStream 

                       |---- StringBufferInputStream            |----   FilterInputStream   |---- DataInputStream

                       |---- ByteArrayInputStream                                                     |---- BufferdInputStream

   7.1 InputStream 的基本方法(都有 throws IOException)

  •  abstract int  read() ;//從輸入流中讀取數據的下一個字節的整型表示(asii碼值),遇到末尾是返回-1

  •  int  read(byte [] b) ;//從輸入流中讀取b.length個字節的數據存入b中,返回實際讀取到的字節總數。

  •  int  read(byte [] b,int off,int len); //讀取len個字節的數據,從off寫入。

  •  void close (); //關閉此輸入流,並釋放與此流相關聯的所有系統資源

  •  long skip(long n); // 跳過和丟棄此輸入流中數據的n個字節,返回丟棄的字節數

  •  int   available (); //返回此輸入流下一個方法可以(不受阻塞)讀取(或跳過)的估計字節數,碰到末尾返回0

8.OutputStream  抽象類

     繼承OutputStream的流是程序用於向外輸出數據的,且數據單位爲一個字節

     OutputStream  |---- FileOutputStream (節點流)          |---- ObjectOutputStream (處理流)

                           |---- PipedOutputStream                    |---- FilterOutputStream |---- DataOutputStream

                           |---- ByteArrayOutputStream                                                 |----  BufferedOutputStream

     8.1 OutputStream  基本方法 (都有 throws IOException)

  •  abstract  void write (int b) ;//將指定的字節(對應asii碼)寫入此輸出流

  •  void write (byte []b) ;//將b.length個字節寫入此輸出流。

  •  void write (byte []b,int off,int len) ;//從off開始,寫入len個字節

  •  void flush() ;//刷新此輸出流並強制寫出所有緩衝的輸出字節。

  •  void close(); //關閉此流,並釋放相關資源

9. Reader 抽象類

    繼承Reader 的流都是向程序輸入數據,數據單位爲一個字符(16位)

    Reader |---- PipedReader (節點流)         |---- BufferedReader  |---- LineNumberReader (處理流) 

               |---- StringReader(節點流)         |---- FilterReader  |---- PushbackReader  (處理流)

               |---- CharArrayReader(節點流)   |---- InputStreamReader (處理流)|---- FileReader(節點流)

   9.1 Reader 的基本方法

  •  int  read();//讀取單個字符,以整型數值返回,達到末尾返回-1

  •  int  read( char[] c);// 讀入char數組中,返回實際讀取的字符數。

  •  int  read(char [] c,int off,int len);//讀取len個字符,並從off開始寫入

  •  void close();//關閉流,並釋放相關資源

  •  long skip(long n);//跳過n個字符

10. Writer 抽象類

        繼承Writer的流是程序用於向外輸出數據的,且數據單位爲一個字符(16位)。

       Writer |---- PipedWriter(節點流)    |----  BufferedWriter (處理流)

                |---- CharArrayWriter         |----  PrintWriter  (處理流)

                |---- StringWriter               |----  OutputStreamWriter(處理流) |---- FileWriter(節點流) 

   10.1 Writer 的基本方法

  •  void writer (int c) ;//寫入單個字符

  •  void  writer (char [] c);//寫入字符數組

  •  void  writer (char [] c,int off, int len);//寫入len個字符

  •  void  writer (String str);//寫入字符串

  •  void  writer (String str,int off,int len);//寫入字符串的某一部分

  •  void  flush();//強制將緩衝的數據寫到目的地

  •  void close();//關閉此流,但要先刷新它

 11. 節點流類型

   

注意:

標準輸入輸出流

默認輸入設備是鍵盤,輸出設備是顯示器。

System.in的類型是InputStream.

System.out的類型是PrintStream是OutputStream的子類FilterOutputStream 的子類

 12. 文件流

       文件流主要用於操作文件

       JDK提供了4種:

  • FileInputStream繼承自InputStream

  • FileOutputStream繼承自OutputStream

  • FileReader繼承自Reader的InputStreamReader

  • FileWriter繼承自Writer的OutputStreamWriter

 13.轉換流

     在IO包中,有字節流和字符流,但是還存在轉換流:字節流-字符流。

     轉換流用於字節流和字符流之間轉換

     JDK提供了兩種轉換流

       InputStreamReader: 是Reader的子類,將輸入的字節流變爲字符流,即將一個字節流的

                                       輸入對象變成字符流的輸入對象。

       OutputStreamWriter:是Writer的子類,將輸出的字符流變成字節流,即將一個字符流的

                                       輸出對象變爲字節流的輸出對象。

       

14. 內存流

      內存流主要用於操作內存

      ByteArrayInputStream 和 ByteArrayOutputStream

          輸入和輸出可以從文件中來,也可以設置在內存之上。   

         ByteArrayInputStream主要完成將內容從內存讀入程序之中,ByteArrayOutputStream

         主要是將數據寫入內存中。

15.緩衝流

      緩衝流是建立在相應的節點流之上,對讀寫的數據提供了緩衝的功能,提高了讀寫的效率,還增加了一些新方法

     JDK提供四種緩衝流:

          BufferedInputStream 可以對任何的InputStream 流進行包裝。

        BufferedOutputStream 可以對任何的OutputStream流進行包裝。

          BufferedReader 可以對任何的Reader流進行包裝:新增了readLine()方法用於一次讀取一行字符串('\r'或'\n'爲一行結束)

          BufferedWriter 可以對任何的Writer流進行包裝:新增了newLine()方法涌入寫入一個行分隔符。

      注意: 對於緩衝輸出流,最好在關閉此流前用flush() 方法將緩存區的數據刷新。

               關閉處理流,會自動關閉所包裝的所有底層流

16.數據流

      DataInputStream ,DataOutputStream 屬於處理流。提供了可以存取與機器無關的Java基本數據類型的方法

      構造方法:參數爲一字節型的節點流

                  DataInputStream (InputStream in);

                  DataOutputStream (OutputStream out);

17.打印流

      PrintStream 和PrintWriter 都屬於輸出流,分別針對字節和字符。

      兩者:都提供了一系列重載的print和println方法輸出各種類型的數據

      兩者:的輸出操作不會拋出異常,System.out.就是PrintStream的一個實例

18.對象流

     JDK提供的ObjectOutputStream和ObjectInputStream 類是用於存儲和讀取基本數據類型或對象的處理流

  • 用ObjectOutputStream類保存基本數據類型或對象的機制叫序列化

  • 用ObjectInputStream類讀取基本數據類型或對象的機制叫反序列化

    注意:能被序列化象所對應的類必須實現java.io.Serializable這個標識性接口

19.管道流(Piped) 

    PipedInputStream(PipedReader) ,PipedOutputStream(PipedWriter) 適合於線程之間的通信

    使用管道流類,可以實現各個程序模塊之間的鬆耦合通信,而不用對模塊內部進行修改。達到“強內聚,弱耦合”的特點。

20.RandomAccessFile 類

     主要功能是完成隨機讀取功能,可以讀取指定位置的內容

文件的打開模式:
“r” 以只讀方式打開。調用結果對象的任何write 方法都將導致拋出IOException。
“rw” 打開以便讀取和寫入。如果該文件尚不存在,則嘗試創建該文件。
“rws” 打開以便讀取和寫入,對於“rw”,還要求對文件的內容或元數據的每個更新都同步寫入到底層存儲設備。
"rwd" 打開以便讀取和寫入,對於"rw",還要求對文件內容的每個更新都同步寫入到底層存儲設備。

21.編碼問題解決方法

法一:java.lang.string

//法一: xx編碼-->new String(byte[]b,Charset xx)-->Stirng.getBytes(Charset yy)-->yy編碼
    public static void method_1() throws Exception
    {
         FileInputStream fis=new FileInputStream ("F:\\test\\test.txt"); 
         File f=new File("F:\\test\\copy-test2.txt");
         if(!f.exists())
             f.createNewFile();
         FileOutputStream fos=new FileOutputStream(f);
         
         byte [] b=new byte[10];
         int len=0;
         while((len=fis.read(b))!=-1)
        {    
             //思路:GB2312 到UTF-8,必須通過一箇中間編碼介質,這裏是String
             //將字節數組轉換爲string (其編碼與操作系統一樣是GBK)
             //再將String轉成其他編碼的字節數組
                  String s=new String(b,0,len,"GB2312");
                  b=s.getBytes("UTF-8");
          //fos.write(b,0,len);注意:這裏是錯誤的,因爲轉碼後的字節數組的長度變了,不是原來長度的字節數組
                  fos.write(b);
         }
         if(fos!=null)
           fos.close();
         if(fis!=null)
             fis.close();
    }

法二:java.io.InputStreamReader/OutputStreamWriter:橋轉換

//法二(推薦):【IO流】xx編碼-->inputstreamreader(file,"xx")--->outputStreamWriter(file,"yy")-->yy編碼
    public static void method_2()throws Exception
    {
         FileInputStream fis=new FileInputStream ("F:\\test\\test.txt"); 
         File f=new File("F:\\test\\copy-test.txt");
         if(!f.exists())
             f.createNewFile();
         FileOutputStream fos=new FileOutputStream(f);
         //io流轉接
         InputStreamReader isr=new InputStreamReader(fis,"GB2312");
         OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
         //讀取:
         char [] cs=new char[1024];
         int len=0;
         while((len=isr.read(cs))!=-1)
        {
             osw.write(cs,0,len);
         }
         //關閉流
        osw.flush();
        osw.close();
        isr.close();
    }

方法三:java.nio.Charset

 總結:

    思路:1.明確源頭,目的地是什麼,內存,硬盤文件。

                 鍵盤(System.in屬於inputstream),控制檯(System.out.屬於printstrem,outputstream)

             2.流向,是輸入,還是輸出。

             3.操作的數據類型,是字符還是字節

             4.有哪些適合的包裝流(處理流)適合題目要求,是緩衝流,數據流,內存流,轉換流。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章