javaIO流

Java流類圖結構:

這裏寫圖片描述

流的概念和做用

流是一組有順序的,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。即數據在兩設備間的傳輸稱爲流,流的本質是數據傳輸,根據數據傳輸特性將流抽象爲各類類,方便更直觀的進行數據操做。java

IO流的分類

  • 根據處理數據類型的不一樣分爲:字符流和字節流
  • 根據數據流向不一樣分爲:輸入流和輸出流

字符流和字節流

字符流的由來: 由於數據編碼的不一樣,而有了對字符進行高效操做的流對象。本質其實就是基於字節流讀取時,去查了指定的碼錶。 字節流和字符流的區別:數組

  • 讀寫單位不一樣:字節流以字節(8bit)爲單位,字符流以字符爲單位,根據碼錶映射字符,一次可能讀多個字節。
  • 處理對象不一樣:字節流能處理全部類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。app

  • 字節流:一次讀入或讀出是8位二進制。
  • 字符流:一次讀入或讀出是16位二進制。函數

設備上的數據不管是圖片或者視頻,文字,它們都以二進制存儲的。二進制的最終都是以一個8位爲數據單元進行體現,因此計算機中的最小數據單元就是字節。意味着,字節流能夠處理設備上的全部數據,因此字節流同樣能夠處理字符數據。編碼

結論:只要是處理純文本數據,就優先考慮使用字符流。 除此以外都使用字節流。

輸入流和輸出流

輸入流只能進行讀操做,輸出流只能進行寫操做,程序中須要根據待傳輸數據的不一樣特性而使用不一樣的流。spa

輸入字節流 InputStream

  • InputStream 是全部的輸入字節流的父類,它是一個抽象類。
  • ByteArrayInputStreamStringBufferInputStreamFileInputStream 是三種基本的介質流,它們分別從Byte 數組StringBuffer、和本地文件中讀取數據。
  • PipedInputStream 是從與其它線程共用的管道中讀取數據,與Piped 相關的知識後續單獨介紹。
  • ObjectInputStream 和全部FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。

輸出字節流 OutputStream

  • OutputStream 是全部的輸出字節流的父類,它是一個抽象類。
  • ByteArrayOutputStreamFileOutputStream 是兩種基本的介質流,它們分別向Byte 數組、和本地文件中寫入數據。
  • PipedOutputStream 是向與其它線程共用的管道中寫入數據。
  • ObjectOutputStream 和全部FilterOutputStream 的子類都是裝飾流。

總結:線程

  • 輸入流:InputStream或者Reader:從文件中讀到程序中;
  • 輸出流:OutputStream或者Writer:從程序中輸出到文件中;

節點流

節點流:直接與數據源相連,讀入或讀出。
直接使用節點流,讀寫不方便,爲了更快的讀寫文件,纔有了處理流。
這裏寫圖片描述code

經常使用的節點流

  • 父 類 :InputStream 、OutputStream、 Reader、 Writer
  • 文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件進行處理的節點流
  • 數 組 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 對數組進行處理的節點流(對應的再也不是文件,而是內存中的一個數組)
  • 字符串 :StringReader、 StringWriter 對字符串進行處理的節點流
  • 管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 對管道進行處理的節點流

處理流

處理流和節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。如BufferedReader.處理流的構造方法老是要帶一個其餘的流對象作參數。一個流對象通過其餘流的屢次包裝,稱爲流的連接。
這裏寫圖片描述視頻

經常使用的處理流

  • 緩衝流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增長緩衝功能,避免頻繁讀寫硬盤。
  • 轉換流:InputStreamReader 、OutputStreamReader實現字節流和字符流之間的轉換。
  • 數據流: DataInputStream 、DataOutputStream 等-提供將基礎數據類型寫入到文件中,或者讀取出來。

轉換流

InputStreamReader 、OutputStreamWriter 要InputStreamOutputStream做爲參數,實現從字節流到字符流的轉換。對象

構造函數

InputStreamReader(InputStream);        //經過構造函數初始化,使用的是本系統默認的編碼表GBK。
InputStreamWriter(InputStream,String charSet);   //經過該構造函數初始化,能夠指定編碼表。
OutputStreamWriter(OutputStream);      //經過該構造函數初始化,使用的是本系統默認的編碼表GBK。
OutputStreamwriter(OutputStream,String charSet);   //經過該構造函數初始化,能夠指定編碼表。

實戰演練

  • FileInputStream類的使用:讀取文件內容
package com.app;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class A1 {

    public static void main(String[] args) {
        A1 a1 = new A1();
    
        //電腦d盤中的abc.txt 文檔
        String filePath = "D:/abc.txt" ;
        String reslut = a1.readFile( filePath ) ;
        System.out.println( reslut ); 
    }


    /**
     * 讀取指定文件的內容
     * @param filePath : 文件的路徑
     * @return  返回的結果
     */
    public String readFile( String filePath ){
        FileInputStream fis=null;
        String result = "" ;
        try {
            // 根據path路徑實例化一個輸入流的對象
            fis  = new FileInputStream( filePath );

            //2. 返回這個輸入流中能夠被讀的剩下的bytes字節的估計值;
            int size =  fis.available() ;
            //3. 根據輸入流中的字節數建立byte數組;
            byte[] array = new byte[size];
            //4.把數據讀取到數組中;
            fis.read( array ) ; 

            //5.根據獲取到的Byte數組新建一個字符串,而後輸出;
            result = new String(array); 

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            if ( fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return result ;
    }


}
  • FileOutputStream 類的使用:將內容寫入文件
package com.app;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class A2 {

    public static void main(String[] args) {
        A2 a2 = new A2();

        //電腦d盤中的abc.txt 文檔
        String filePath = "D:/abc.txt" ;

        //要寫入的內容
        String content = "今天是2017/1/9,天氣很好" ;
        a2.writeFile( filePath , content  ) ;

    }

    /**
     * 根據文件路徑建立輸出流
     * @param filePath : 文件的路徑
     * @param content : 須要寫入的內容
     */
    public void writeFile( String filePath , String content ){
        FileOutputStream fos = null ;
        try {
            //一、根據文件路徑建立輸出流
            fos  = new FileOutputStream( filePath );

            //二、把string轉換爲byte數組;
            byte[] array = content.getBytes() ;
            //三、把byte數組輸出;
            fos.write( array );

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            if ( fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}

注意:

  1. 在實際的項目中,全部的IO操做都應該放到子線程中操做,避免堵住主線程。
  2. FileInputStream在讀取文件內容的時候,咱們傳入文件的路徑("D:/abc.txt"), 若是這個路徑下的文件不存在,那麼在執行readFile()方法時會報FileNotFoundException異常。
  3. FileOutputStream在寫入文件的時候,咱們傳入文件的路徑("D:/abc.txt"), 若是這個路徑下的文件不存在,那麼在執行writeFile()方法時, 會默認給咱們建立一個新的文件。還有重要的一點,不會報異常。

效果圖:

這裏寫圖片描述

  • 綜合練習,實現複製文件,從D盤複製到E盤
package com.app;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class A3 {

    public static void main(String[] args) {
        A3 a2 = new A3();

        //電腦d盤中的cat.png 圖片的路徑
        String filePath1 = "D:/cat.png" ;

        //電腦e盤中的cat.png 圖片的路徑
        String filePath2 = "E:/cat.png" ;

        //複製文件
        a2.copyFile( filePath1 , filePath2 );

    }

    /**
     * 文件複製 
     * @param filePath_old : 須要複製文件的路徑
     * @param filePath_new : 複製文件存放的路徑
     */
    public void copyFile( String filePath_old  , String filePath_new){
        FileInputStream fis=null ;
        FileOutputStream fout = null ;
        try {
            // 根據path路徑實例化一個輸入流的對象
            fis  = new FileInputStream( filePath_old );

            //2. 返回這個輸入流中能夠被讀的剩下的bytes字節的估計值;
            int size =  fis.available() ;
            //3. 根據輸入流中的字節數建立byte數組;
            byte[] array = new byte[size];
            //4.把數據讀取到數組中;
            fis.read( array ) ; 

            //五、根據文件路徑建立輸出流
            fout = new FileOutputStream( filePath_new ) ;
            
            //五、把byte數組輸出;
            fout.write( array );

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            if ( fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if ( fout != null ) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }   
            }
        }
    }
}
相關文章
相關標籤/搜索