首頁 > 軟體

JavaIO字元操作和物件操作範例詳解

2023-02-06 06:01:55

字元操作

編碼與解碼

編碼就是把字元轉換為位元組,而解碼是把位元組重新組合成字元。

如果編碼和解碼過程使用不同的編碼方式那麼就出現了亂碼。

  • GBK 編碼中,中文字元佔 2 個位元組,英文字元佔 1 個位元組;
  • UTF-8 編碼中,中文字元佔 3 個位元組,英文字元佔 1 個位元組;
  • UTF-16be 編碼中,中文字元和英文字元都佔 2 個位元組。

UTF-16be 中的 be 指的是 Big Endian,也就是大端。相應地也有 UTF-16le,le 指的是 Little Endian,也就是小端。

Java 的記憶體編碼使用雙位元組編碼 UTF-16be,這不是指 Java 只支援這一種編碼方式,而是說 char 這種型別使用 UTF-16be 進行編碼。char 型別佔 16 位,也就是兩個位元組,Java 使用這種雙位元組編碼是為了讓一箇中文或者一個英文都能使用一個 char 來儲存。

String 的編碼方式

String 可以看成一個字元序列,可以指定一個編碼方式將它編碼為位元組序列,也可以指定一個編碼方式將一個位元組序列解碼為 String。

String str1 = "中文";
byte[] bytes = str1.getBytes("UTF-8");
String str2 = new String(bytes, "UTF-8");
System.out.println(str2);

在呼叫無引數 getBytes() 方法時,預設的編碼方式不是 UTF-16be。雙位元組編碼的好處是可以使用一個 char 儲存中文和英文,而將 String 轉為 bytes[] 位元組陣列就不再需要這個好處,因此也就不再需要雙位元組編碼。getBytes() 的預設編碼方式與平臺有關,一般為 UTF-8。

byte[] bytes = str1.getBytes();

Reader 與 Writer

不管是磁碟還是網路傳輸,最小的儲存單元都是位元組,而不是字元。但是在程式中操作的通常是字元形式的資料,因此需要提供對字元進行操作的方法。

  • InputStreamReader 實現從位元組流解碼成字元流;
  • OutputStreamWriter 實現字元流編碼成為位元組流。

實現逐行輸出文字檔案的內容

public static void readFileContent(String filePath) throws IOException {
    FileReader fileReader = new FileReader(filePath);
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String line;
    while ((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }
    // 裝飾者模式使得 BufferedReader 組合了一個 Reader 物件
    // 在呼叫 BufferedReader 的 close() 方法時會去呼叫 Reader 的 close() 方法
    // 因此只要一個 close() 呼叫即可
    bufferedReader.close();
}

物件操作

序列化

序列化就是將一個物件轉換成位元組序列,方便儲存和傳輸。

  • 序列化:ObjectOutputStream.writeObject()
  • 反序列化:ObjectInputStream.readObject()

不會對靜態變數進行序列化,因為序列化只是儲存物件的狀態,靜態變數屬於類的狀態。

Serializable

序列化的類需要實現 Serializable 介面,它只是一個標準,沒有任何方法需要實現,但是如果不去實現它的話而進行序列化,會丟擲異常。

public static void main(String[] args) throws IOException, ClassNotFoundException {
    A a1 = new A(123, "abc");
    String objectFile = "file/a1";
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(objectFile));
    objectOutputStream.writeObject(a1);
    objectOutputStream.close();
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(objectFile));
    A a2 = (A) objectInputStream.readObject();
    objectInputStream.close();
    System.out.println(a2);
}
private static class A implements Serializable {
    private int x;
    private String y;
    A(int x, String y) {
        this.x = x;
        this.y = y;
    }
    @Override
    public String toString() {
        return "x = " + x + "  " + "y = " + y;
    }
}

transient

transient 關鍵字可以使一些屬性不會被序列化。

ArrayList 中儲存資料的陣列 elementData 是用 transient 修飾的,因為這個陣列是動態擴充套件的,並不是所有的空間都被使用,因此就不需要所有的內容都被序列化。通過重寫序列化和反序列化方法,使得可以只序列化陣列中有內容的那部分資料。

private transient Object[] elementData;

以上就是JavaIO字元操作和物件操作範例詳解的詳細內容,更多關於JavaIO字元操作物件操作的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com