“嗨,阿米戈!”
“現在是時候討論另一個有趣的話題了:編碼。”
“也許你已經在某處聽說過,每個字符都有一個代碼(數字)。這就是為什麼 char 類型可以同時表示符號和數字的原因。”
》比如英文字母‘A’的編碼是65,‘B’是66,‘C’是67,等等。大寫字母、小寫字母、西里爾字母、中文都有唯一的編碼字符(是的,很多很多代碼)、數字和各種符號。簡而言之,幾乎所有你稱之為字符的東西都有一個代碼。”
“那麼,每個字母和字符都對應著某個數字?”
“恰恰。”
“字符可以轉換為數字,數字可以轉換為字符。Java 通常看不出它們之間的區別:”
char c = 'A'; //The code (number) for 'A' is 65
c++; //Now c contains the number 66, which is the code for 'B'
“有趣的。”
“因此,編碼是一組符號及其對應的一組代碼。但不僅發明了一種編碼——還有相當多的編碼。直到後來才發明了一種通用的通用編碼 Unicode。”
“但無論發明了多少通用標準,沒有人急於放棄舊標準。然後一切都像這部卡通片一樣發生:”

“想像一下,文森特和尼克決定製作他們自己的編碼。”
“這是文森特的編碼:”
“這是尼克的編碼:”
“他們甚至使用相同的字符,但字符的代碼不同。”
“當使用 Vincent 編碼將字符串‘ABC-123’寫入文件時,我們得到以下字節集:”
“現在另一個使用 Nick 編碼的程序想要讀取文件:”
“這是它的內容:«345-IJK»。”
“最糟糕的是,編碼通常不會存儲在文件中的任何位置,因此開發人員不得不猜測。”
“嗯,他們怎麼猜的?”
“那是一個不同的話題。但我想解釋一下如何使用編碼。正如您已經知道的那樣,Java 中 char 的大小是兩個字節。Java 字符串使用 Unicode 格式。”
“但是 Java 允許您將 String 轉換為它所知道的任何編碼的一組字節。String 類對此有特殊的方法。Java 也有一個特殊的 Charset 類來描述特定的編碼。”
1) 如何獲得 Java 支持的所有編碼列表?
“為此有一個名為 availableCharsets 的特殊靜態方法。“此方法返回一組對(編碼名稱,描述編碼的對象):”
SortedMap<String,Charset> charsets = Charset.availableCharsets();
“每種編碼都有一個唯一的名稱。以下是其中的一些名稱:UTF-8、UTF-16、Windows-1251、KOI8-R,……”
2) 如何獲得當前的活動編碼 (Unicode)?
“為此有一個名為defaultCharset的特殊方法。
Charset currentCharset = Charset.defaultCharset();
3) 如何將字符串轉換為特定的編碼?
“在 Java 中,您可以使用 Java 知道的任何編碼將字符串轉換為字節數組:”
方法 | 例子 |
---|---|
|
|
|
|
|
|
4) 如果我知道文件中的編碼是什麼,如何將從文件讀取的字節數組轉換為字符串?
“這更容易。String 類有一個特殊的構造函數:”
方法 | 例子 |
---|---|
|
|
|
|
|
|
5) 如何將字節數組從一種編碼轉換為另一種編碼?
“有很多方法。這是最簡單的一種:”
Charset koi8 = Charset.forName("KOI8-R");
Charset windows1251 = Charset.forName("Windows-1251");
byte[] buffer = new byte[1000];
inputStream.read(buffer);
String s = new String(buffer, koi8);
buffer = s.getBytes(windows1251);
outputStream.write(buffer);
“我就是這麼想的。謝謝你的有趣教訓,Rishi。”
GO TO FULL VERSION