20.Java語言IO流、IO流異常處理、以及Properties

IO流

I :Input(輸入)數據從外部流入程序(硬盤到內存)

O:Output(輸出)數據從程序流出外部(內存到硬盤)

流:類似於水流—有方向,線性

作用:

可以讀寫文件的內容

體系:

A).字節流:按字節讀寫文件。可以操作任何類型文件

           1).輸出流:OutputStream(抽象類)

                      |--FileOutputStream(子類)

           2).輸入流:InputStream(抽象類)

                     |--FileInputStream(子類)

B).字符流:按“字符讀寫文件。僅僅可以讀、寫純文本文件。

           1).輸出流:Writer(抽象類)

                     |--OutputStreamWriter(轉換流)

                         |--FileWriter(子類)

           2).輸入流:Reader(抽象類)

                     |--InputStreamReader(轉換流)

                         |--FileReader(子類)

IO流圖解:

 

字節流

一切皆爲字節,“字節流”是Java中IO流的最基本的流,任何的其它流(字符流、打印流....)都是基於字節流的

1字節輸出流OutputStream:

OutputStream(抽象類) à 子類:FileOutputStream

      輸出的方法;

      1).write(int b)            輸出一個字節

      2).write(byte[] byteArray)       輸出一個字節數組

      3).write(byte[] byteArray,int off,int len)輸出一個字節數組的部分,起始位置和長度

2字節輸出流子類FileOutputStream:

       構造方法:

       1). FileOutputStream​(String name) :使用指定的文件名構造一個輸出流 覆蓋寫

       2). FileOutputStream​(File file) 創建文件輸出流以寫入由指定的 File對象表示的文件。覆蓋寫

       3). FileOutputStream​(File file, boolean append) 創建文件輸出流以寫入由指定的 File對象表示的文件。追加寫

       4). FileOutputStream​(String name, boolean append) 創建文件輸出流以指定的名稱寫入文件。 追加寫

       輸出的方法:(無特有,都是從父類繼承的)

       1).write(int b):輸出一個字節(很少用)

       2).write(byte[] byteArray):輸出一個字節數組(常用:write("你好".getBytes()))

       3).write(byte[] byteArray,int off,int len):輸出一個字節數組的一部分(很少用)。

       注意:

              1).Java中任何的輸出流,構造時文件都可以不存在,會自動創建一個空文件

              2).Java的IO流不要構造在一個“存在的目錄上”,否則運行時異常。

              3).三種輸出的方法都是無返回值的,每次調用方法都會寫入一次內容

public static void main(String[] args) throws IOException {
    File file = new File("demo.txt");
    FileOutputStream out1 = new FileOutputStream(file);
    FileOutputStream out2 = new FileOutputStream(file,true);
    FileOutputStream out3 = new                    FileOutputStream("demo.txt");
    FileOutputStream out4 = new FileOutputStream("demo.txt",true);
    int b = 97;
    byte[] array = new byte[4];
    out1.write(b);
    out1.write(array);
    out1.write(array,0,3);
    String s = "我愛Java";
    out1.write(s.getBytes(),0,3);//一個漢字是三個字節
}

寫出換行

Windows系統裏,換行符號是 \r\n

fos.write("\r\n".getBytes());

3字節輸入流InputStream:

       InputStream(抽象類) à 子類: FileInputStream

       讀取的方法:

       1).public int read():依次讀取一個字節;

       2).public int read(byte[] byteArray):依次讀取一個字節數組;

       3).public int read(byte[] byteArray,int off,int len)讀取一個字節數組的部分,起始位置和長度

4.字節輸入流的子類FileInputStream:

       構造方法:

       1).FileInputStream(String pathname):

       2).FileInputStream(File file):

//構造方法

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

FileInputStream in1 = new FileInputStream(file);

FileInputStream in2 = new FileInputStream("demo.txt");

       注意:

       1).Java中所有的“輸入流”構造時,文件必須存在,否則運行時異常。

       讀取的方法(從父類繼承):

       1).public int read():讀取一個字節;返回讀取的字節對應編碼,兩次調用會連續讀取兩個字節

       2).public int read(byte[] byteArray):讀取一個字節數組;返回每次讀取的字節個數,讀取的字節覆蓋數組原有的內容,如果讀取一個返回1覆蓋數組第一個內容,如果沒有讀取到內容返回-1

3).write(byte[] byteArray,int off,int len)輸出一個字節數組的部分,起始位置和長度返回讀取的字節數

byte[] b = new byte[4];
System.out.println(in1.read());
System.out.println(in1.read());
in1.read(b,0,3);
while ((a = in1.read(b)) != -1) {
    System.out.println(Arrays.toString(b));
}

//結果
// 97
//98
//[99, 100, 101, 102]
//[103, 100, 101, 102]

5.字節流文件複製案例:

       首先按照字節流讀入文件,然後按照字節流輸出文件,所以需要一個輸入流一個輸出流

       示例代碼:

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

    //首先讀取文件,創建輸入流
    FileInputStream in = new FileInputStream("demo.txt");

    //然後寫入文件,創建輸出流
    FileOutputStream out = new    FileOutputStream("demo_copy.txt");

    //1,一個字節的讀取,一個字節的寫入
    int b = 0;
    while ((b = in.read()) != -1) {
        out.write(b);
    }

    //2.一個字節數組的輸入和輸出
    byte[] byteArray = new byte[3];
    while ((b = in.read(byteArray)) != -1) {
        //最後一次輸入的字節個數不一定
        //所以輸出用部分輸出的方式
        out.write(byteArray,0,b);
    }
    in.close();
    out.close();
}

 

字符流

按照一次一個字符讀取和寫入,因爲每個國家的字符的字節數不同,如果按照一個字節的方式比較麻煩,所以Java提供了只能操作純文本字符流的方式,

1.字符輸出流Writer:

       Writer(抽象類) à OutputStreamWriter(轉換流) à FileWriter(子類)

       輸出的方法:

       1).write(int c):輸出一個字符;

       2).write(char[] chArray):輸出一個字符數組

       3).write(char[] chArray,int off,int len):輸出字符數組的一部分;

       4).write(String s):輸出一個字符串;

       5).write(String s,int off,int len):輸出字符串的一部分。

2.字符輸出流子類FileWriter:

       構造方法:

       1).FileWriter​(String fileName) 構造一個給定文件名的FileWriter對象。

       2).FileWriter​(File file) 給一個File對象構造一個FileWriter對象。 

       3).FileWriter​(String fileName, boolean append) 構造一個給定帶有布爾值的和文件名FileWriter對象。表示是否追加寫入的數據。

4).FileWriter​(File file, boolean append) 給一個File對象和布爾值構造一個FileWriter對象。  表示是否追加寫入的數據。

       輸出的方法(全部從父類繼承):

       1).write(int c):輸出一個字符;

       2).write(char[] chArray):輸出一個字符數組

       3).write(char[] chArray,int off,int len):輸出字符數組的一部分;

       4).write(String s):輸出一個字符串;

       5).write(String s,int off,int len):輸出字符串的一部分。

       注意:

       1).字符流輸出完之後必須刷新或者關閉,關閉有刷新的功能,否則內容在緩存區不會被寫入文件

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

    //構造方法:
    File file = new File("demo.txt");
    FileWriter out1 = new FileWriter(file);
    FileWriter out2 = new FileWriter(file,true);
    FileWriter out3 = new FileWriter("demo.txt",true);
    FileWriter out4 = new FileWriter("demo.txt");

    //輸出方法:
    char[] array = {'a','b','c'};
    out1.write(97);
    out1.write(array);
    out1.write(array,0,2);
    out1.write("java");
    out1.write("java",0,3);

    //關閉刷新
    out1.close();

}

關閉和刷新:

因爲內置緩衝區的原因,如果不關閉輸出流,無法寫出字符到文件中。但是關閉的流對象,是無法繼續寫出數據的。

如果我們既想寫出數據,又想繼續使用流,就需要 flush 方法了。

flush() :刷新緩衝區,流對象可以繼續使用。

close() :關閉流,釋放系統資源。關閉前會刷新緩衝區。

字符輸入流Reader:

Reader(抽象類) à InputStreamWriter(轉換流) à FileReader(子類)

       讀取的方法:

       1).int read():讀取一個字符。返回:讀取的字符的編碼值;int類型

       2).int read(char[] chArray):讀取一個字符數組;返回值:讀取的字符數量。

字符輸入流子類FileReader:

       構造方法:

       1).FileReader(String path):

       2).FileReader(File file):

       輸入的方法:

       1).public int read():依次讀取一個字節;

       2).public int read(byte[] byteArray):依次讀取一個字節數組;

3).public int read(byte[] byteArray,int off,int len)讀取一個字節數組的部分,起始位置和長度

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

    //構造方法
    File file = new File("demo.txt");
    FileReader in1 = new FileReader(file);
    FileReader in2 = new FileReader("demo.txt");

    //讀取方法
    char[] arr = new char[4];
    in1.read();
    in1.read(arr);
    in1.read(arr, 0, 2);
}

IO異常處理

JDK7之前,使用 try...catch...finally代碼塊處理異常部分

JDK7,使用try-with-resource處理,自動關閉每個資源

JDK9,對於引入對象的方式,支持的更加簡潔,也是自動關閉資源

Properties

       java.util.Properties(類):此類是一個Map集合。此類中有兩個方法可以用於方便的讀、寫配置文件;

配置文件

指軟件運行過程中記錄用戶的一些設置信息的文件,這種配置文件在國際上有一個通用的格式:

                     名1 = 值

                     名2 = 值

                     名3 = 值

                     ....

這種格式同Map的鍵值對格式正好匹配,所以Java製作了一個Properties類來方便的讀寫配置文件。

使用:

       1).Properties集合-->配置文件:store()方法

       2).配置文件-->Properties集合:load()方法

代碼示例:

public class Properties_添加到文件 {

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

        FileWriter out = new FileWriter("demo.txt");
        Properties ps = new Properties();
        ps.setProperty("姓名1", "姓名11");
        ps.setProperty("姓名2", "姓名22");
        ps.setProperty("姓名3", "姓名33");
        ps.store(out,"名單");
        out.close();
    }
}
public class Properties_讀取文件內容 {

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

        Properties ps = new Properties();
        FileReader in = new FileReader("demo.txt");
        ps.load(in);
        //stringPropertyNames()返回Set<String>集合
        for (String s : ps.stringPropertyNames()) {
            System.out.println(ps.get(s));
        }
    }
}

 

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