Java IO流(詳細)

Jeson-Sun發表於2020-12-09

IO流

:可以理解為是一個資料的序列,輸入流代表從一個源讀取資料,輸出流表示將資料寫入一個目標中。
在這裡插入圖片描述

什麼是IO流:用來輸出輸入的流,也可以理解為IO流就是以流的方式來進行輸出輸入。

在這裡插入圖片描述

  1. 水源地是產水的地方(相當於是源)
  2. 自來水廠的水從哪來呢?從水源地輸入。(相當於IO流中的輸入流)
  3. 自來水廠的水要去哪呢?他將輸出到使用者手中。(相當於IO流中的輸出流)

緩衝區:一個用於基本資料型別的容器。
為什麼我們想要水就會有水呢?那是因為使用者和自來水廠之間有一個儲水池。同樣Java中也有一個儲水池,叫做緩衝區。
在這裡插入圖片描述

IO流都有啥
在這裡插入圖片描述
在這裡插入圖片描述
IO流分類

  • 根據流的資料流向可分為
  1. 位元組流 (抽象基類:InputStream和OutputStream )
  2. 字元流 (抽象基類:Writer和Reader )
  • 根據流中處理資料的單位可分為
  1. 輸入流
  2. 輸出流

Write字元輸出流
在這裡插入圖片描述

  • FileWriter
  1. 例:建立一個檔案demo.txt
 package java_demo.IO流;

import java.io.FileWriter;
import java.io.IOException;

public class Filewrite {
    public static void main(String args[]) throws IOException {
        FileWriter file = null;
        try {
	        //建立一個FileWriter物件。該物件一被初始化就必須要明確被操作的檔案。
	        //而且該檔案會被建立到指定目錄下。如果該目錄下已有同名檔案,將被覆蓋。
	        //其實該步就是在明確資料要存放的目的地。
            file = new FileWriter("filedemo.text",true);
            file.write("我叫小豬!\n");//呼叫write方法,將字串寫入到流中。
        }catch (IOException e) {
            System.out.println(e.toString());
        }
        finally {
            try {
                if(file != null)
                {
                    file.close();//關閉流
                }
            }catch (IOException e)
            {
                System.out.println(e.toString());
            }
        }
    }
}
  • BufferedWriter
  1. BufferedWriter是一個快取字元輸出流,他的作用是為其他字元輸出流提供快取。
  2. 例:
 package java_demo.IO流;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Bufferedwriter {
    public static void main(String args[]) throws IOException
    {
        FileWriter file = new FileWriter("filedemo.text",true);
        BufferedWriter bw = new BufferedWriter(file);//把為了提高字元寫入流效率。加入了緩衝技術。只要將需要被提高效率的流物件作為引數傳遞給緩衝區的建構函式即可。
        char [] a = {'a','b','c','d','e','f'};
        bw.write(a,0,4);
        bw.newLine();
        bw.write(a,2,2);
        bw.flush();
        bw.close();
    }
}

Reader字元輸入流:
在這裡插入圖片描述

  • FileReader
  1. 例:
package java_demo.IO流;

import java.io.*;

public class Filereader {
    public static void main(String[] args) throws IOException
    {
        //建立一個檔案讀取流物件,和指定名稱的檔案相關聯。
        //要保證該檔案是已經存在的,如果不存在,會發生異常FileNotFoundException
        FileReader fr = new FileReader("filedemo.text");

        //呼叫讀取流物件的read方法。
        //read():一次讀一個字元。而且會自動往下讀。

        int ch = 0;

        while((ch=fr.read())!=-1)
        {
            System.out.println("ch="+(char)ch);
        }

        //關閉流
        fr.close();

    }
}
  • BufferReader
  1. 例:
package java_demo.IO流;
import java.io.*;

public class Bufferedreader {
    public static void main(String[] args) throws IOException
    {
        //建立一個讀取流物件和檔案相關聯。
        FileReader fr = new FileReader("filedemo.text");

        //為了提高效率。加入緩衝技術。將字元讀取流物件作為引數傳遞給緩衝物件的建構函式。
        BufferedReader bufr = new BufferedReader(fr);


        String line = null;

        while((line=bufr.readLine())!=null)
        {
            System.out.print(line);
        }
        //關閉流
        bufr.close();
    }
}

InputStream位元組輸出流
InputStream類是位元組輸入流的抽象類,是所有位元組輸入流的父類,InputStream類具有層次結構如下圖所示:
在這裡插入圖片描述

  • FileInputStream
  1. 例:
 package java_demo.IO流;
import java.io.*;

public class FileStream {
    public static void main(String[] args) throws IOException
    {
        readFile_3();
    }

    //開啟檔案,一次讀取剛剛好內容的位元組
    public static void readFile_3()throws IOException
    {
        FileInputStream fis = new FileInputStream("fos.txt");

        //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();
    }

}

OutputStream直接輸出流
OutputStream位元組輸出流,是所有位元組輸出流的父類,InputStream類具有層次結構如下圖所示:
在這裡插入圖片描述

  • FileInputStream
  1. 例:
package java_demo.IO流;
import java.io.*;
public class Fileinputstream {
    private static final String FileName = "fos.txt";

    public static void main(String[] args) {
        testWrite();
    }

    /**
     * FileOutputStream 演示函式
     *
     * 執行結果:
     * 在原始碼所在目錄生成檔案"file.txt",檔案內容是“abcdefghijklmnopqrstuvwxyz0123456789”
     *
     * 加入,我們將 FileOutputStream fileOut2 = new FileOutputStream(file, true);
     *       修改為 FileOutputStream fileOut2 = new FileOutputStream(file, false);
     * 然後再執行程式,“file.txt”的內容變成"0123456789"。
     * 原因是:
     * (01) FileOutputStream fileOut2 = new FileOutputStream(file, true);
     *      它是以“追加模式”將內容寫入檔案的。即寫入的內容,追加到原始的內容之後。
     * (02) FileOutputStream fileOut2 = new FileOutputStream(file, false);
     *      它是以“新建模式”將內容寫入檔案的。即刪除檔案原始的內容之後,再重新寫入。
     */
    public static void testWrite() {
        try {
            // 建立檔案“file.txt”對應File物件
            File file = new File(FileName);
            // 建立檔案“file.txt”對應的FileOutputStream物件,預設是關閉“追加模式”
            FileOutputStream fileOut1 = new FileOutputStream(file);
            // 建立FileOutputStream對應的PrintStream,方便操作。PrintStream的寫入介面更便利
            PrintStream out1 = new PrintStream(fileOut1);
            // 向“檔案中”寫入26個字母
            out1.print("abcdefghijklmnopqrstuvwxyz");
            out1.close();

            // 建立檔案“file.txt”對應的FileOutputStream物件,開啟“追加模式”
            FileOutputStream fileOut2 = new FileOutputStream(file, true);
            // 建立FileOutputStream對應的PrintStream,方便操作。PrintStream的寫入介面更便利
            PrintStream out2 = new PrintStream(fileOut2);
            // 向“檔案中”寫入"0123456789"+換行符
            out2.println("0123456789");
            out2.close();

        } catch(IOException e) {
            e.printStackTrace();
        }
    }

}