Java | IO流

概述

Java程序中,對於數據的輸入/輸出操做以「流(stream)」的方式進行。數組

流的分類

  • 按操做數據單位的不一樣分爲:字節流(8bit)字符流(16 bit)
  • 按數據流的流向不一樣分爲:輸入流輸出流
  • 按流的角色不一樣分爲:節點流處理流

關於字節流和字符流的區別:單元測試

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

輸入流和輸出流測試

  • 輸入流只能進行讀操做
  • 輸出流只能進行寫操做

節點流和處理流 spa

節點流:直接從數據源或者目的地讀寫數據3d

image.png

處理流:不直接鏈接到數據源或目的地,而是「鏈接」在已存在的流(節點流或處理流)之上,經過對數據的處理爲程序提供更爲強大的讀寫功能。
image.pngcode

Java IO流體系 對象

Java中IO流體系以下表所示,最基本的四個抽象基類分別是:InputStreamOutputStreamReaderWriter。表格每一列的類都是繼承與第一行的抽象基類的。blog

IO流體系圖

經常使用的字符流

FileReader

一般一個流的使用由如下4個步驟組成:繼承

  1. 提供File類的對象,指明要操做的文件
  2. 提供具體的流
  3. 根據不一樣流,進行不一樣的操做
  4. 流的關閉操做

好比以FileReader流爲例,那麼它的使用步驟是:圖片

  1. 實例化File類的對象,指明要操做的文件
  2. 提供具體的流,FileReader流的實例化
  3. 進行數據的讀入操做
  4. 流的關閉操做

雖然Java IO流體系有衆多的類,可是全部的流都基本按照這幾個步驟來使用的。下面記錄一下FileReader的使用,數據的讀入操做。

@Test
    public void testFileReader() throws IOException { // 拋出異常
        // 1. 實例化File類對象,指明要操做的文件
        File file = new File("Hello.txt");
        // 2. 提供具體的流
        FileReader fr = new FileReader(file);
        // 3. 數據的讀入
        // read():返回讀入的一個字符,若是達到文件末尾,那麼返回-1
        int data = fr.read();
        while(data != -1){
            System.out.print((char)data);
            data = fr.read();
        }
        // 4. 流的關閉操做
        fr.close();
    }

上面例子中,經過File類實例化了一個File對象,而後將其當作參數傳入了FileReader類進行實例化,以後調用read()方法進行數據的讀入,最後執行流的關閉。

關於上面代碼有幾個須要注意的點:

  • File file = new File("Hello.txt");這段代碼使用的是相對路徑,若是是使用IDEA進行編寫的,那麼這個相對路徑在單元測試方法和main方法中有所區別。在單元測試方法中使用相對路徑,那麼相對的是模塊的路徑,而在main方法中相對的是項目的路徑。好比,這裏模塊名Day07,這個模塊下有文件Hello.txt,而模塊位於項目JavaSenior下,那麼File類實例化後的實例文件路徑以下代碼所示:
public class FileReaderTest {
    // 在main方法中,輸出:D:\code\Java\JavaSenior\Hello.txt
    public static void main(String[] args) {
        File file = new File("Hello.txt");
        System.out.println(file.getAbsolutePath());
    }
    
     // 在單元測試方法中,輸出:D:\code\Java\JavaSenior\Day07\Hello.txt
    @Test
    public void test4(){
        File file = new File("Hello.txt");
        System.out.println(file.getAbsolutePath());
    }
}
  • 因爲建立流不能被Java垃圾回收機制所處理,因此須要手動進行流的關閉操做,可是因爲異常,在步驟1,2,3可能出現異常致使第4步(流的關閉)不能被執行,致使資源不能及時回收,因此爲了保證資源必定能夠執行關閉操做,須要使用try-catch-finally進行處理,而不建議使用拋出的方式。因此,比較規範的流使用代碼應該以下:
@Test
    public void test2(){
        FileReader fr = null;
        try{
            File file = new File("Hello.txt");
            fr = new FileReader(file);
            int data;
            while ((data = fr.read()) != -1){
                System.out.println((char)data);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (fr != null){
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
  • read()方法:讀取單個字符。做爲整數讀取的字符,範圍在0-65535之間(2個字節的Unicode碼),若是已到達流的末尾,則返回-1。
  • read(char cbuf[]):將字符存入數組,而且返回本次讀取的字符數,若是到達流的末尾,則返回-1。
@Test
    public void test3()  {
        FileReader fr = null;
        try {
            // 1. File類的實例化
            File file = new File("Hello.txt");

            // 2. FileReader流的實例化
            fr = new FileReader(file);

            // 3. 讀入的操做
            char[] cbuf = new char[5];
            int len;
             /*
             假如Hello.txt裏的文件內容是helloworld123,這裏的read(cbuf)指的是讀取5個字符,
             即第一次讀取hello,返回5,第二次讀取world,返回5,
             第三次讀取123,由於只有123了,返回3,第四次返回-1。
             因此3次循環,len變量的值爲5,5,3,最後一次爲-1。
             */
            while ((len = fr.read(cbuf)) != -1) {
                // 遍歷操做錯誤的寫法
//                for (int i = 0; i < arr.length; i++) {
//                    System.out.println(arr[i]);
//                }
                // 正確的遍歷操做一:
//                for (int i = 0; i < len; i++) {
//                    System.out.print(arr[i]);
//                }

                // 錯誤的寫法二:
//                String str = new String(arr);
//                System.out.println(str);

                // 正確的寫法二:
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 4. 流資源的關閉
            try {
                if (fr != null) {
                    fr.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

未完待續...

相關文章
相關標籤/搜索