IO流(02)--屬性集、緩衝流、轉換流

??魯阿豔??發表於2020-12-16

屬性集【Properties】

java.util.Properties類繼承於Hashtable,用來表示一個持久的屬性集。它使用鍵值結構儲存資料,每個鍵及其對應的值都是一個字串。

構造方法
  • ​ public Properties():建立一個空的屬性集列表。
共性的api方法
  • public Object setProperty(String key,String value):儲存一對屬性。
  • public String getProperty(String key):使用此屬性列表中的指定的鍵搜尋對應的值。
  • public Set stringPropertyNames():獲取所有鍵的名稱並封裝到Set集合中。
public static void main(String[] args) {
        // 建立屬性集物件
        Properties properties = new Properties();
        // 新增鍵值對元素
        properties.setProperty("name", "abc.txt");
        properties.setProperty("size", "12000");
        properties.setProperty("destination","D:\\abc.txt");
        properties.put("data","小孫");
        System.out.println(properties);// {destination=D:\abc.txt, name=abc.txt, size=12000}

        // 通過鍵來獲取值
        String data = properties.getProperty("data");
        System.out.println(data); // 小孫
        String size = properties.getProperty("size");
        System.out.println(size);// 12000

        // 遍歷該屬性集
        // public Set<String> stringPropertyNames():獲取所有鍵的名稱並封裝到Set集合中。
        Set<String> keys = properties.stringPropertyNames();
        // 遍歷keys
        for (String key : keys) {
            // 通過key獲取value
            String value = properties.getProperty(key);
            System.out.println(key + "=" + value);
        }

    }
與流相關的方法
  • public void load(InputStream input):從位元組輸入流中讀取鍵值對

引數中使用了位元組輸入流,通過流物件,可以關聯到某個檔案上,這樣既可以載入檔案中的資料。檔案中的資料的格式:key=value

例如:
   data=小孫
   size=12000  
   name=abc.txt

程式碼演示:

public static void show01() throws IOException {
        // 0.構建一個流物件
        FileReader fr = new FileReader("day29_IO\\abc.txt");
        // 1.建立Properties集合
        final Properties properties = new Properties();
        //  2.使用Properties集合中的方法load讀取儲存在輸入流中的資料
        properties.load(fr);
        //  3.遍歷Properties集合
        final Set<String> set = properties.stringPropertyNames();
        for (String key : set) {
            // 通過key獲取value值
            final String value = properties.getProperty(key);
            System.out.println(key + "=" + value);
        }
        /*
            name=abc.txt
            size=12000
            data=小孫
            目的地=D:\abc.txt
         */
    }
  • ​ public void store(OutputStream out,String comments):把集合當中資料寫入位元組輸出流中

可以使用Properties集合當中的方法store,把集合當中的臨時資料,持久化寫入到硬碟檔案中儲存。

程式碼示例:

public static void show02() throws IOException {
        // 1. 建立Properties集合物件,新增資料
        final Properties properties = new Properties();
        properties.setProperty("四大名著1","紅樓夢");
        properties.setProperty("四大名著2","西遊記");
        properties.setProperty("四大名著3", "水滸傳");
        properties.setProperty("四大名著4", "三國演義");
        // 2. 建立位元組輸出流/字元輸出流物件,構造方法中繫結需要寫入資料的目的地
        final FileWriter fw = new FileWriter("day29_IO\\abcd.txt", true);
        // 3. 使用Properties集合中的方法store,把集合當中的臨時資料,持久化寫入到硬碟當中儲存
        properties.store(fw, "si da ming zhu");
        // 4.釋放資源。
        fw.close();
}

緩衝流【Buffered】

緩衝流我們理解為對原來的使用陣列方式進行資料傳輸的一種增強

按照型別分為:

  • 字元緩衝流:BufferedReader,BufferedWriter
  • 位元組緩衝流:BufferedInputStream,BufferedOutputStream

緩衝流的基本原理,是在建立流物件的時候,會建立一個內建的預設大小的緩衝區陣列,通過緩衝區讀寫資料,減少系統IO操作的次數,減少開銷,提高程式的讀寫的效率。

位元組緩衝流
構造方法
  • public BufferedInputStream(InputStream input):建立一個新的緩衝輸入流
  • public BufferedOutputStream(OutputStream output):建立一個新的緩衝輸出流

程式碼示例:

public class Demo02 {
    public static void main(String[] args) throws IOException {
        // 1.建立一個FileOutputStream流物件,構造方法中標的需要繫結寫入資料的資料來源
        FileInputStream fis = new FileInputStream("day29_IO\\one.txt");
        // 2.建立BufferedInputStream物件,構造方法中傳遞FileInputStream流物件
        BufferedInputStream bis = new BufferedInputStream(fis);
        //3.使用BufferedInputStream物件指定方法read,把資料讀取到記憶體中
        /*int len = 0;
        while ((len=bis.read())!=-1){
            System.out.println((char)len);
        }*/
        byte[]bytes = new byte[1024];
        int len = 0;
        while ((len=bis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        //4.釋放資源
        bis.close();
    }
}

字元緩衝流

構造方法

  • public BufferedWriter(Writer out):建立一個 新的字元緩衝輸出流

  • public BufferedReader(Reader in):建立一個新的字元緩衝輸入流。

特有方法:

  • BufferedReader: public String readLine():讀取整行的文字資訊

  • BufferedWriter: public void newLine():寫入一行的行分隔符,由系統屬性定義換行符號。

字元緩衝輸入流程式碼演示:

public static void main(String[] args) throws IOException {
        //1.建立一個字元緩衝輸入流物件,構造方法中傳入一個字元輸入流
        BufferedReader br = new BufferedReader(new FileReader("day29_IO\\abc.txt"));
        //2.使用字元緩衝流物件中的read/readLine,
       /* String str = br.readLine();
        System.out.println(str);*/
        //迴圈結束條件readLine()返回值是null的時候
        String str = null;
        while ((str=br.readLine())!=null){
            System.out.println(str);
        }
        //3.釋放資源。
        br.close();
    }

字元緩衝輸出流程式碼演示:

public static void main(String[] args) throws IOException {
        // 1.建立一個字元緩衝輸出流物件,構造方法中傳遞一個字元輸出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("day29_IO\\two.txt"));
        //2.呼叫字元流物件中的writer,把資料寫入到記憶體儲存區中
        bw.write("我今天學習了PS,雖然沒學會");
        bw.newLine();
        bw.write("3D軟體mmd");
        bw.newLine();
        bw.write("c4d");
        // 3.呼叫字元緩衝輸出流物件的flush方法,把你想緩衝區的資料重新整理到檔案中
        bw.flush();
        //4.釋放資源
        bw.close();
    }

練習:

 public static void show02() throws IOException {
        long start = System.currentTimeMillis();
        //1.構建位元組緩衝輸入流物件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\0.jpg"));
        //2.構建個位元組緩衝輸出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\code\\java31\\day29_IO\\0.jpg"));
        //3.用位元組緩衝輸入流物件中的方法read(byte[] b)讀取檔案
        byte[]bytes = new byte[1024];

        int len = 0;//記錄讀取到有效位元組個數
        while ((len = bis.read(bytes))!=-1){
            //節內容再次寫入到目的地檔案中,呼叫write
            bos.write(bytes,0,len);
        }
        bos.close();
        bis.close();

        long end= System.currentTimeMillis();
        System.out.println("檔案複製耗費的時間為:"+(end-start));
    }

轉換流【位元組流<-->字元流】

  • 字元編碼:
      按照某種規則將字元儲存到計算機中,稱為編碼;反之,將儲存在計算機中的二進位制數按照某種規則解析顯示出來,稱為解碼。在進行編碼或者解碼的過程中,我們採用的是同一種規則,才能資料正常,否則,就會導致亂碼現象。就是一套自然語言中的字元與二進位制數直接的對應規則。

  • 字符集:
      是一個系統可支援的所有字元的集合,包括各國文字,標點符號,圖形符號,數字等,也叫編碼表。

計算機中要準確的儲存和識別各種文字的字元符號,需要進行字元編碼,一套字符集至少有一套字元編碼。

常見的字元編碼集有ASCII字符集,GBK字符集、Unicode字符集。

ASCII字符集:

  • ASCII是基於拉丁字母的一套編碼系統,用於顯示現代英語。

  • 基本的ASCII字符集,使用7位(bit)表示一個字元,共128個字元。ASCII的擴充套件字符集使用8位(bit)表示一個字元,共25
    6個字元。

ISO—8859-1字符集

  • 拉丁碼錶,別名--Lanlin-1,用於顯示歐洲使用的語言,包括荷蘭,丹麥,德語,義大利語,西班牙語等。

  • ISO-8859-1使用單位元組編碼,相容ASCII編碼。

GB系列符集

  • CB2312:稱為簡體中文碼錶裡面大概含有7000多個簡體漢字,此外數字符號。羅馬希臘的字母,日本的假名都編進去了,連在ASCII裡的原來就有的數字、標點、字母都統統重新用兩個位元組編寫進去了。

  • GBK:最常用的中文碼錶。是在原來的GB2312碼錶基礎上進行了擴充套件。也是使用雙位元組編碼。共收錄了21000多個漢字,完全相容GB2312標準,同時支援繁體漢字以及日韓漢字等。

  • GB18030:最新的中文碼錶,共收錄了7萬多個漢字,採用多位元組編碼,每個字可以由1個位元組、2個位元組或者是4個位元組組成,支援國內少數民族的文字。同時也支援繁體字以及日韓漢字等。

Unicode字符集:

  • Unicode編碼系統為表達任意語言的任意字元而設計的,是業界的一種標準,也稱為統一編碼,標準萬國碼表

  • 它最多使用4個位元組的數字來表示某個字母、符號、漢字文字,有三種常見的編碼方案:UTF-8,UTF-6,UTF-32.

  • UTF-8編碼表,用來表示Unicode標準中的任意字元,編碼規則:

  1.128個US-ASCII字元,使用的是一個位元組編碼
  2.拉丁字的字母,需要兩個位元組編碼
  3.大部分常見的漢字,使用的是三個位元組編碼
  4.其他極少數的輔助字元,採用的四個位元組編碼。

編碼會引發的問題

由於編碼規則不一致,導致引發亂碼現象。

那麼如何讀取GBK編碼的檔案呢?

InputStreamReader類

轉換流 java.io.InputStreamReader 是Reader的子類,它是從位元組流到字元流的橋樑。它讀取位元組,並使用指定的字符集將其解碼為字元。它的字符集可以由名稱指定,或者可以使用平臺預設的字符集。

構造方法
  • public InputStreamReader(InputStream in):建立一個使用預設的字符集的字元流。

  • public InputStreamReader(InputStream in,String charseName):建立一個指定字符集的字元流

程式碼演示:

 public static void show01() throws IOException {
        //1.建立InputStreamReader物件,構造方法中傳遞位元組輸入流和指定的編碼表名稱
        InputStreamReader isr = new InputStreamReader(new FileInputStream("day29_IO\\新建文字文件.txt"), "GBK");
        //2.使用InputStreamReader物件中的方法read讀取檔案中的資訊
        int len = 0;
        while ((len=isr.read())!=-1) {
            System.out.println((char)len);
        }
        //3.釋放資源。
        isr.close();
    }

OutStreamWriter類

轉換流java.io.OtputSreamWiter是Writer的子類,它是字元流到位元組流的橋樑。使用指定的字符集將字元編碼為位元組。它的字符集可以手動指定,也可以使用平臺預設的字符集。

構造方法:

  • public OutputStreamWriter(OutputStream out): 建立一個使用普通預設的字符集的字元流。

  • public OutputStreamWriter(OutputStream out,String charseName):建立一個指定的字符集字元流。

相關文章