1. 程式人生 > >Java檔案操作及編碼總結

Java檔案操作及編碼總結

編碼/解碼 編碼:getBytes(); 按照預設編碼表編碼 字串-------->位元組 解碼:new String(); 按照預設編碼表解碼 位元組------->>字串

GBK 碼錶:漢字的儲存,第一個一定是負的。如果轉換器讀到的第一個是正的位元組,那麼他就會拿這個位元組去查碼錶 UTF-8 :對中文的編碼,三個位元組表示一個漢字

“聯通”的問題: 在桌面建立一個記事本檔案,然後複製它。在原始檔中存入字元“聯通” ,在副本中輸入“移動”。都儲存後再開啟副本,會發現副本中是亂碼 原始檔的編碼是預設ANSI。副本的編碼是UTF-8 輸入的是GBK的字元 所以副本就是在解碼的時候出現了問題

UTF-8 的編碼特點;

  1. 能用一個位元組儲存就用一個位元組,開頭為零
  2. 一個位元組存不下就用兩個位元組。規定:第一個位元組的開頭為110,第二個位元組的開頭為10 這是規定死的。
  3. 兩個位元組都裝不下,那就用三個位元組儲存,第一個位元組開頭:1110;第二個位元組開頭為;10; 第三個位元組開頭為:10 U8 的讀取方式: 通過位元組的開頭來判斷他是哪一類位元組,就按照多少個位元組讀取

而“聯通” 這個字元的GBK編碼二進位制剛好符合U8 的編碼規律,所以記事本在解析這段二進位制時就啟動了U8 的碼錶來解析這段資料。 其實只要聯通後面跟上了其他資料就不會發生亂碼,因為在讀取碼的時候一次會讀入一堆位元組

—————————————————————————————————————————————————

字元流緩衝區以及readLine() 的原理: BufferedReader = new BufferedReaderleWriter(file))

緩衝區的原理:在緩衝區中有一個緩衝陣列,將讀取出的字元都全部存在緩衝陣列中,外部用完後再次,從底層讀取。在readLine() 中也有一個緩衝陣列,每次從BufferedReader 的緩衝區中讀取一行(讀到結束的識別符號/換行,,)但是不會將結束符讀入,也就是說在readLine 的緩衝陣列陣列中一次儲存了一行的字元 程式碼:

package IO;

import java.io.IOException;
import java.io.Reader;

//在清楚了緩衝的原理後,自己寫一個緩衝區,緩衝的的精髓就在於有一個做緩衝的陣列
//簡易版
public class MyBufferedReader {
  //要有一個字元陣列
     private char[] buff = new char[1024];
    private Reader r;
    //從陣列中獲取資料,就要有索引
    private int index;
    //記錄獲取的資料個數,當獲取晚了緩衝陣列中的資料才再從底層裝置讀取
     private int cunt =0 ;

    public MyBufferedReader(Reader r){//緩衝區是對流操作的所以在初始化的時候就要有流
        this.r = r;
    }
    //讀取一行字元
    public String readLine() throws IOException {
        //有一個緩衝容器
        StringBuilder sb = new StringBuilder();
       //使用本類的read 方法,從緩衝區讀取一行字元,讀取的時候注意,不儲存行終止符
        int ch = 0;
        while((ch = this.Read())!=-1){
                if(ch=='\r'){
                    continue;//繼續讀取但是不儲存
                }
                if(ch=='\n'){
                    return sb.toString();
                }
                sb.append((char)ch);
        }
        //萬一最後一行文字沒有換行符,則判斷一下sb  中是否有內容,由內容則返回sb
        if(sb.length()!=0){
            return sb.toString();
        }
        return null;
    }
    //對外提供方法 讀取單個字元
    public int Read() throws IOException {
        if(cunt==0){//緩衝陣列中沒有資料時才讀取
            cunt = r.read(buff);//通過流物件從底層將讀取的字元儲存到緩衝區的陣列中
            index = 0;//每一次重新讀資料,索引要歸零
        }
        if(cunt<0){
            return -1;
        }
        int ch = buff[index];
        index++;//取出資料後索引向後移動
        cunt--;//個數減少
        return ch;
    }
    //關閉流
    public void close() throws IOException {
        r.close();
    }
}

關於對檔案的操作的總結: 在這裡插入圖片描述 在這裡插入圖片描述

緩衝區的意義:儘量將底層的操作封裝,位元組緩衝區,讀取時的自己傳入的陣列(也是儲存和緩衝的作用)到緩衝類中的緩衝陣列,都是將資料儘量的向上推出,每一步的操作儘量止於當前的方法,不會說我每一次呼叫方法都要從最底層的硬碟上去操作一次