IO【字節流、高效流】


第11天 IO流
今日內容介紹
    字節流
    緩衝流
今日學習目標
    可以使用字節輸出流寫出數據到文件
    可以使用字節輸入流讀取數據到程序
    可以理解讀取數據read(byte[])方法的原理
    可以使用字節流完成文件的複製
    可以使用字節緩衝流讀取數據到程序
    可以使用字節緩衝流寫出數據到文件
    可以完成單級文件夾複製
第1章    IO
1.1    IO概述
回想以前寫過的程序,數據都是在內存中,一旦程序運行結束,這些數據都沒有了,等下次再想使用這些數據,但是已經沒有了。那怎麼辦呢?能不能把運算完的數據都保存下來,下次程序啓動的時候,再把這些數據讀出來繼續使用呢?其實要把數據持久化存儲,就須要把內存中的數據存儲到內存之外的其餘持久化設備(硬盤、光盤、U盤等 ROM)上。
當須要把內存中的數據存儲到持久化設備上這個動做稱爲輸出(寫)Output操做。
當把持久設備上的數據讀取到內存中的這個動做稱爲輸入(讀)Input操做。
所以咱們把這種輸入和輸出動做稱爲IO操做。數組


1.2    IO流流向分類
按照流向分:輸入流與輸出流,每一個IO流對象均要綁定一個IO資源
分類關係以下:
字節輸入流 InputStream 抽象類
FileInputStream 操做文件的字節輸入流
字節輸出流 OutputStream 抽象類
FileOutputStream 操做文件的字節輸出流
按照傳輸方式:分爲字節流和字符流
   字符流  按照字符的方式讀寫
   字節流  按照字節的方式讀寫

1.3    一切均爲字節
在數據傳輸過程當中,一切數據(文本、圖像、聲音等)最終存儲的均爲一個個字節,即二進制數字。因此數據傳輸過程當中使用二進制數據能夠完成任意數據的傳遞。
爲何打開一個文本文件 咱們看到的不是0101001這些數據?
咱們向一個文件中存儲必定的數據(一些數字),若是使用文本方式打開,則會以文本的方式解釋數據。若是以視頻的方式打開,則會以視頻的方式解釋數據。音頻、可行執行文件等亦是如此。因此,在文件傳輸過程當中,咱們要時刻明確,傳輸的始終爲二進制數據。函數

第2章    字節流
既然一切數據都是字節,那麼字節流如何操做呢,那麼接下來咱們進行字節流的學習.
2.1    字節輸出流OutputStream
OutputStream此抽象類,是表示輸出字節流的全部類的超類。操做的數據都是字節,定義了輸出字節流的基本共性功能方法。
輸出流中定義都是寫write方法,以下圖:學習


2.1.1    FileOutputStream類
OutputStream有不少子類,其中子類FileOutputStream可用來寫入數據到文件。
FileOutputStream類,即文件輸出流,是用於將數據寫入 File的輸出流。spa

    構造方法code

2.1.2    FileOutputStream類寫入數據到文件中(三個方法)
    將數據寫到文件中,
    步驟
    1.建立輸出流對象
    2.調用輸出流對象的寫數據方法
    3.釋放資源
    代碼演示:視頻

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //需求:將數據寫入到文件中。
        //建立存儲數據的文件。
        File file = new File("c:\\file.txt");
        //建立一個用於操做文件的字節輸出流對象。一建立就必須明確數據存儲目的地。
        //輸出流目的是文件,會自動建立。若是文件存在,則覆蓋。
        FileOutputStream fos = new FileOutputStream(file);
        //調用父類中的write方法。
        byte[] data = "abcde".getBytes();
        fos.write(data);
        //關閉流資源。
        fos.close();
    }
}

2.1.3    給文件中續寫和換行
咱們直接new FileOutputStream(file)這樣建立對象,寫入數據,會覆蓋原有的文件,那麼咱們想在原有的文件中續寫內容怎麼辦呢?
繼續查閱FileOutputStream的API。發如今FileOutputStream的構造函數中,能夠接受一個boolean類型的值,若是值true,就會在文件末位繼續添加。
    構造方法對象


    給文件中續寫數據和換行,代碼演示:blog

public class FileOutputStreamDemo2 {
    public static void main(String[] args) throws Exception {
        File file = new File("c:\\file.txt");
        FileOutputStream fos = new FileOutputStream(file, true);
        String str = "\r\n"+"itcast";
        fos.write(str.getBytes());
        fos.close();
    }
}

2.2    字節輸入流InputStream
經過前面的學習,咱們能夠把內存中的數據寫出到文件中,那如何想把內存中的數據讀到內存中,咱們經過InputStream能夠實現。InputStream此抽象類,是表示字節輸入流的全部類的超類。,定義了字節輸入流的基本共性功能方法。內存


    int read():讀取一個字節並返回,沒有字節返回-1.
    int read(byte[]): 讀取必定量的字節數,並存儲到字節數組中,返回讀取到的字節數。
2.2.1    FileInputStream類
InputStream有不少子類,其中子類FileInputStream可用來讀取文件內容。
FileInputStream 從文件系統中的某個文件中得到輸入字節。資源


    構造方法


2.2.2    FileInputStream類讀取數據read方法(只讀純英文,有空介紹一下讀中文問題)
在讀取文件中的數據時,調用read方法,實現從文件中讀取數據


    從文件中讀取數據,代碼演示:

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("c:\\file.txt");
        //建立一個字節輸入流對象,必須明確數據源,其實就是建立字節讀取流和數據源相關聯。
        FileInputStream fis = new FileInputStream(file);
        //讀取數據。使用 read();一次讀一個字節。
        int ch = 0;
        while((ch=fis.read())!=-1){
            System.out.println("ch="+(char)ch);
        }
        // 關閉資源。
        fis.close();
    }
}

2.2.3    讀取數據read(byte[])方法
在讀取文件中的數據時,調用read方法,每次只能讀取一個,太麻煩了,因而咱們能夠定義數組做爲臨時的存儲容器,這時能夠調用重載的read方法,一次能夠讀取多個字符。

public class FileInputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        /*          * 演示第二個讀取方法, read(byte[]);          */
        File file = new File("c:\\file.txt");
        // 建立一個字節輸入流對象,必須明確數據源,其實就是建立字節讀取流和數據源相關聯。
        FileInputStream fis = new FileInputStream(file);        
        //建立一個字節數組。
        byte[] buf = new byte[1024];//長度能夠定義成1024的整數倍。      
        int len = 0;
        while((len=fis.read(buf))!=-1){
            System.out.println(new String(buf,0,len));
        }
        fis.close();
    }
}

2.3    字節流練習
既然會了文件的讀和寫操做了,那麼咱們就要在這個基礎上進行更爲複雜的操做。使用讀寫操做完成文件的複製。
2.3.1    複製文件
原理;讀取一個已有的數據,並將這些讀到的數據寫入到另外一個文件中。

public class CopyFileTest {
    public static void main(String[] args) throws IOException {
        //1,明確源和目的。
        File srcFile = new File("c:\\YesDir\test.JPG");
        File destFile = new File("copyTest.JPG");

        //2,明確字節流 輸入流和源相關聯,輸出流和目的關聯。
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        //3, 使用輸入流的讀取方法讀取字節,並將字節寫入到目的中。
        int ch = 0;
        while((ch=fis.read())!=-1){
            fos.write(ch);
        }
        //4,關閉資源。
        fos.close();
        fis.close();
    }
}

上述代碼輸入流和輸出流之間是經過ch這個變量進行數據交換的。
上述複製文件有個問題,每次都從源文件讀取一個,而後在寫到指定文件,接着再讀取一個字符,而後再寫一個,一直這樣下去。效率極低。
2.3.2    臨時數組方式複製文件
上述代碼複製文件效率過低了,而且頻繁的從文件讀數據,和寫數據,能不能一次多把文件中多個數據都讀進內容中,而後在一次寫出去,這樣的速度必定會比前面代碼速度快。

public class CopyFileByBufferTest {
    public static void main(String[] args) throws IOException {
        File srcFile = new File("c:\\YesDir\test.JPG");
        File destFile = new File("copyTest.JPG");
        // 明確字節流 輸入流和源相關聯,輸出流和目的關聯。
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        //定義一個緩衝區。
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);// 將數組中的指定長度的數據寫入到輸出流中。
        }
        // 關閉資源。
        fos.close();
        fis.close();
    }
}

第3章    緩衝流
在咱們學習字節流與字符流的時候,你們都進行過讀取文件中數據的操做,讀取數據量大的文件時,讀取的速度會很慢,很影響咱們程序的效率,那麼,我想提升速度,怎麼辦?
Java中提升了一套緩衝流,它的存在,可提升IO流的讀寫速度
緩衝流,根據流的分類分類字節緩衝流與字符緩衝流。
在基礎班咱們已經學習過字符緩衝流了,那麼今天學習一下字節緩衝流。
3.1    字節緩衝流
字節緩衝流根據流的方向,共有2個
    寫入數據到流中,字節緩衝輸出流 BufferedOutputStream
    讀取流中的數據,字節緩衝輸入流 BufferedInputStream

它們的內部都包含了一個緩衝區,經過緩衝區讀寫,就能夠提升了IO流的讀寫速度
3.1.1    字節緩衝輸出流BufferedOutputStream
經過字節緩衝流,進行文件的讀寫操做 寫數據到文件的操做  
    構造方法
public BufferedOutputStream(OutputStream out)建立一個新的緩衝輸出流,以將數據寫入指定的底層輸出流。

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

        //寫數據到文件的方法
        write();
    }

    /*      * 寫數據到文件的方法      * 1,建立流      * 2,寫數據      * 3,關閉流      */
    private static void write() throws IOException {
        //建立基本的字節輸出流
        FileOutputStream fileOut = new FileOutputStream("abc.txt");
        //使用高效的流,把基本的流進行封裝,實現速度的提高
        BufferedOutputStream out = new BufferedOutputStream(fileOut);
        //2,寫數據
        out.write("hello".getBytes());
        //3,關閉流
        out.close();
    }
}

3.1.2    字節緩衝輸入流 BufferedInputStream
剛剛咱們學習了輸出流實現了向文件中寫數據的操做,那麼,如今咱們完成讀取文件中數據的操做
    構造方法
public BufferedInputStream(InputStream in)

    /*      * 從文件中讀取數據      * 1,建立緩衝流對象      * 2,讀數據,打印      * 3,關閉      */
    private static void read() throws IOException {
        //1,建立緩衝流對象
        FileInputStream fileIn = new FileInputStream("abc.txt");
        //把基本的流包裝成高效的流
        BufferedInputStream in = new BufferedInputStream(fileIn);
        //2,讀數據
        int ch = -1;
        while ( (ch = in.read()) != -1 ) {
            //打印
            System.out.print((char)ch);
        }
        //3,關閉
        in.close();
    }

3.1.3    複製單級文件夾

/*   * 數據源:e:\\demo  * 目的地:e:\\test  *   * 分析:  *         A:封裝目錄  *         B:獲取該目錄下的全部文本的File數組  *         C:遍歷該File數組,獲得每個File對象  *         D:把該File進行復制  */
public class CopyFolderDemo {
    public static void main(String[] args) throws IOException {
        // 封裝目錄
        File srcFolder = new File("e:\\demo");
        // 封裝目的地
        File destFolder = new File("e:\\test");
        // 若是目的地文件夾不存在,就建立
        if (!destFolder.exists()) {
            destFolder.mkdir();
        }

        // 獲取該目錄下的全部文本的File數組
        File[] fileArray = srcFolder.listFiles();

        // 遍歷該File數組,獲得每個File對象
        for (File file : fileArray) {
            // System.out.println(file);
            // 數據源:e:\\demo\\e.mp3
            // 目的地:e:\\test\\e.mp3
            String name = file.getName(); // e.mp3
            File newFile = new File(destFolder, name); // e:\\test\\e.mp3

            copyFile(file, newFile);
        }
    }

    private static void copyFile(File file, File newFile) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                file));
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(newFile));

        byte[] bys = new byte[1024];
        int len = 0;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }

        bos.close();
        bis.close();
    }
} 

歡迎關注菜鳥永恆,天天進步一小點。

相關文章
相關標籤/搜索