(Java)IO流

IO流

在這裏插入圖片描述

一切皆爲字節

一切文件數據(文本、圖片、視頻等)在存儲時,都是以二進制數字的形式保存,都一個一個的字節,那麼傳輸時一樣如此。所以,字節流可以傳輸任意文件數據。在操作流的時候,我們要時刻明確,無論使用什麼樣的流對象,底層傳輸的始終爲二進制數據。

字節輸出流【OutputStream】

java.io.OutputStream抽象類是表示字節輸出流的所有類的超類,將指定的字節信息寫出到目的地。它定義了字節輸出流的基本共性功能方法。

  • public void close() :關閉此輸出流並釋放與此流相關聯的任何系統資源。
  • public void flush() :刷新此輸出流並強制任何緩衝的輸出字節被寫出。
  • public void write(byte[] b):將 b.length字節從指定的字節數組寫入此輸出流。
  • public void write(byte[] b, int off, int len) :從指定的字節數組寫入 len字節,從偏移量 off開始輸出到此輸出流。
  • public abstract void write(int b) :將指定的字節輸出流。
    在這裏插入圖片描述

注意:

close方法,當完成流的操作時,必須調用此方法,釋放系統資源。

FileOutputStream類

OutputStream有很多子類,我們從最簡單的一個子類開始。

java.io.FileOutputStream類是文件輸出流,用於將數據寫出到文件。

構造方法

  • public FileOutputStream(File file):創建文件輸出流以寫入由指定的 File對象表示的文件。
  • public FileOutputStream(String name): 創建文件輸出流以指定的名稱寫入文件。

當你創建一個流對象時,必須傳入一個文件路徑。該路徑下,如果沒有這個文件,會創建該文件。如果有這個文件,會清空這個文件的數據。

寫出字節數據

  1. 寫出字節write(int b) 方法,每次可以寫出一個字節數據

小貼士:

  1. 雖然參數爲int類型四個字節,但是隻會保留一個字節的信息寫出。
  2. 流操作完畢後,必須釋放系統資源,調用close方法,千萬記得。
  1. 寫出字節數組write(byte[] b),每次可以寫出數組中的數據

  2. 寫出指定長度字節數組write(byte[] b, int off, int len) ,每次寫出從off索引開始,len個字節

代碼演示

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class Demo02OutPutStream {
    public static void main(String[] args) throws IOException {
        //創建FileOutputStream對象。
        FileOutputStream fos = new FileOutputStream("D:\\b.txt");
        //創建byte數組
        byte[] byte1 = {65,66,67,68,69};
        //當字節是在(1~127)之間時按照ASCII表寫入數據,
        //如果第一個字節爲負數,那第一個字節和第二個字節組成一箇中文顯示,查詢系統默認碼錶(GBK)
        fos.write(byte1);//ABCDE
        /*public void write(byte b[], int off, int len)
            int off:數據的開始索引
            int len:寫幾個字節
        */
        //從數組byte1的1號字節開始寫2個字節
        fos.write(byte1,1,2);//BC
        //將字符串轉換爲字節數組
        byte[] byte2 = "你好".getBytes();
        //輸出字符串轉換的字節數組
        System.out.println(Arrays.toString(byte2));//[-28, -67, -96, -27, -91, -67]
        //將字節數組輸出
        fos.write(byte2);
        ////釋放資源(流使用會佔用一定的內存,使用完畢要把內存清空,提高程序的效率)
        fos.close();
    }
}

在給定的路徑下新創建了一個b.txt文件
在這裏插入圖片描述
寫入的文件內容
在這裏插入圖片描述
你好的字節數組

注:UTF-8編碼,三個字節表示一個漢字;GBK編碼,兩個字節表示一個漢字。

在這裏插入圖片描述

數據追加續寫

經過以上的演示,每次程序運行,創建輸出流對象,都會清空目標文件中的數據。如何保留目標文件中數據,還能繼續添加新數據呢?

  • public FileOutputStream(File file, boolean append): 創建文件輸出流以寫入由指定的 File對象表示的文件。
  • public FileOutputStream(String name, boolean append): 創建文件輸出流以指定的名稱寫入文件。

這兩個構造方法,參數中都需要傳入一個boolean類型的值,true 表示追加數據,false 表示清空原有數據。這樣創建的輸出流對象,就可以指定是否追加續寫了

寫出換行

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

  • 回車符\r和換行符\n
    • 回車符:回到一行的開頭(return)。
    • 換行符:下一行(newline)。
  • 系統中的換行:
    • Windows系統裏,每行結尾是 回車+換行 ,即\r\n
    • Unix系統裏,每行結尾只有 換行 ,即\n
    • Mac系統裏,每行結尾是 回車 ,即\r。從 Mac OS X開始與Linux統一。

代碼演示

import java.io.FileOutputStream;
import java.io.IOException;

public class Demo03OutPutStream {
    public static void main(String[] args) throws IOException {
        //append 爲true時創建對象不會覆蓋源文件,繼續在文件末尾追加數據
        //爲false時創建一個新文件,覆蓋源文件。
        FileOutputStream fos = new FileOutputStream("D:\\c.txt",true);
        byte[] bytes1 = "你好".getBytes();
        byte[] bytes2 = "世界".getBytes();
        //換行
        byte[] bytes = "\r\n".getBytes();
        //寫入換行
        fos.write(bytes);
        //寫入你好
        fos.write(bytes1);
        //寫入換行
        fos.write(bytes);
        fos.write(bytes2);
        //釋放資源
        fos.close();
    }
}

在這裏插入圖片描述

字節輸入流【InputStream】

java.io.InputStream抽象類是表示字節輸入流的所有類的超類,可以讀取字節信息到內存中。它定義了字節輸入流的基本共性功能方法。

  • public void close() :關閉此輸入流並釋放與此流相關聯的任何系統資源。
  • public abstract int read(): 從輸入流讀取數據的下一個字節。
  • public int read(byte[] b): 從輸入流中讀取一些字節數,並將它們存儲到字節數組 b中 。
    在這裏插入圖片描述

小貼士:

close方法,當完成流的操作時,必須調用此方法,釋放系統資源。

FileInputStream類

java.io.FileInputStream類是文件輸入流,從文件中讀取字節。

構造方法

  • FileInputStream(File file): 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。
  • FileInputStream(String name): 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。

當你創建一個流對象時,必須傳入一個文件路徑。該路徑下,如果沒有該文件,會拋出FileNotFoundException

讀取字節數據

  1. 讀取字節read方法,每次可以讀取一個字節的數據,提升爲int類型,讀取到文件末尾,返回-1

代碼演示

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

public class Demo01InPutStream {
    public static void main(String[] args) throws IOException {
        //創建FileInputStream對象
        FileInputStream fis = new FileInputStream("D:\\a.txt");
        int len = 0;
        //循環讀取文件
        //當文件讀取到末尾時會返回-1,所以當len= -1時結束循環
        while (( len = fis.read()) != -1 ){
            //len本身輸出的是abc的字節編碼,強轉爲char後變爲 a b c
            System.out.print((char)len+" "); //a b c
            System.out.println(len);//97 98 99
          
        }
        fis.close();
    }
}

在這裏插入圖片描述

注意:

  1. 雖然讀取了一個字節,但是會自動提升爲int類型。
  2. 流操作完畢後,必須釋放系統資源,調用close方法,千萬記得。
  1. 使用字節數組讀取read(byte[] b),每次讀取b的長度個字節到數組中,返回讀取到的有效字節個數,讀取到末尾時,返回-1 ,代碼使用演示:
import java.io.FileInputStream;
import java.io.IOException;

public class Demo02InPutStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\a.txt");
        //創建字節數組,一次讀取2個字節。 一般爲1024的倍數。
        byte[] b = new byte[2];
        int len = 0;
        //循環讀取
        //一次讀取2個字節
        while ((len = fis.read(b))!=-1){
            System.out.println(new String(b));//String(byte b) 可以將字節轉換爲字符串
        }
        //釋放資源
        fis.close();
    }
}

在這裏插入圖片描述

錯誤數據d,是由於最後一次讀取時,只讀取一個字節e,數組中,上次讀取的數據沒有被完全替換,所以要通過len ,獲取有效的字節,代碼使用演示:

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

public class Demo02InPutStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\a.txt");
        //創建字節數組,一次讀取2個字節
        byte[] b = new byte[2];
        int len = 0;
        //循環讀取
        //一次讀取2個字節
        while ((len = fis.read(b))!=-1){
            System.out.println(new String(b,0,len));//可以將字節轉換爲字符串,0表示從第0個字節開始,len表示長度
        }
        //釋放資源
        fis.close();
    }
}

在這裏插入圖片描述

注意:

使用數組讀取,每次讀取多個字節,減少了系統間的IO操作次數,從而提高了讀寫的效率,建議開發中使用。

字節流練習:圖片複製

複製原理圖解

在這裏插入圖片描述

案例實現

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

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

            //創建一個字節輸入流對象,構造方法中綁定要讀取的數據源
            FileInputStream fis = new FileInputStream("C:\\1.png");
            //創建一個字節輸出流對象,構造方法中綁定要寫入的目的地
            FileOutputStream fos = new FileOutputStream("D:\\2.png");
            int len = 0;
            //使用數組讀取多個字節,寫入多個字節
            byte[] bytes = new byte[1024];
            //使用字節輸入流中的方法read讀取文件
            while ((len = fis.read(bytes))!=-1){
                //使用字節輸出流中的方法read讀取文件
                fos.write(bytes,0,len);
            }
            fis.close();
            fos.close();
    }
}

在這裏插入圖片描述

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