程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Merlin的魔力: 字符集

Merlin的魔力: 字符集

編輯:關於JAVA

用數字表示

不怕明說,其實計算機只理解數字。但下面這一點可能就沒那麼明顯 ― 因為計算機只理解數字,所以它們需要用某種形式把數字值映射為相應的字符,這樣才能顯示文本。就是這些映射(或 字符集)才使得計算機可以理解文本。例如,就為了這種映射,早期的台式機使用了 ASCII。當一台使用 ASCII 的計算機存儲數字 72、101、108 和 112 時,它便知道要顯示“Help”這個單詞,因為在 ASCII 中,數字 72 是 H 的值、101 是 e 的值、108 是 l 的值、112 是 p 的值。但如果這台計算機是早期的 IBM 大型機(它使用 EBCDIC 而不是 ASCII),“Help”這個單詞將用數字 200、133、147 和 151 代表。

字符集基礎知識

在向 Java 語言遷移時, java.nio.charset 包中有三個類幫助進行這種映射: Charset 、 CharsetEncoder 和 CharsetDecoder 。這些類相互配合,這樣您就可以先采用一種映射,然後將其轉換為另一種映射。在從另一種映射轉換為 Java 映射(Unicode)時,您可以使用解碼器(decoder)。然後,如果您需要從 Java 映射(Unicode)再轉換為另一種映射(或轉換回原來那種映射)時,您可以使用編碼器(encoder)。您無法用 java.nio.charset 包在兩種非 Unicode 格式之間直接轉換,但您可以通過一種中間的 Unicode 格式在兩種非 Unicode 格式間進行轉換。

在得到一個解碼器或編碼器之前,您需要獲得用於特定映射的 Charset 。例如,US-ASCII 是用於 7 位 ASCII 字符集的映射的名稱。您只需象下面這樣把該名稱傳遞到 Charset 的 forName() 方法中即可:

Charset charset =
  Charset.forName("US-ASCII");

一旦有了 Charset ,只需按如下所示請求 CharsetDecoder 和 CharsetEncoder :

CharsetDecoder decoder =
  charset.newDecoder();
CharsetEncoder encoder =
  charset.newEncoder();

有了解碼器和編碼器後,您就可以在不同的字符集之間進行轉換了,如下所示:

ByteBuffer bytes = ...;
  CharBuffer chars = decoder.decode(bytes);
  bytes = encoder.encode(chars);

當然,如果不確定哪些字符集可用,您需要用下面的語句來詢問:

SortedMap map =
  Charset.availableCharsets();

然後您將使用特定的解碼器把外部字節轉換為內部字符。然後,如果需要把數據發送到 Java 代碼外,您將使用編碼器把內部字符轉換為外部字節。至於哪些特定的字符集可用,您的運行時將確定整個字符集。但每個 Java 編程實現都必須支持下列編碼:

US-ASCII:7 位 ASCII

ISO-8859-1:ISO 拉丁字母

UTF-8:8 位 UCS 轉換格式

UTF-16BE:16 位 UCS 轉換格式,大尾數法字節順序

UTF-16LE:16 位 UCS 轉換格式,小尾數法字節順序

UTF-16:16 位 UCS 轉換格式,用標記(marker)識別的字節順序

然後,不同的平台可能支持特定於該平台的額外字符集(例如,在 Windows 平台上,您會發現它支持 Windows-1252 字符集)。如果您需要支持其他的字符集,您可以創建自己的字符集。請參閱 java.nio.charset.spi 包中的 CharsetProvider API。

完整的示例

清單 1 通過轉換單詞“Help”的 ASCII 字節數組值(72、101、108 和 112)演示了 Java 字符集轉換功能。遺憾的是,缺省情況下沒有 EBCDIC 編碼器,所以我們將把值轉換為 UTF-16LE 字符數組(這只是為每個字符的第二個字節添加一個“0”字節)。

清單 1. 字符集轉換示例

import java.nio.*;
import java.nio.charset.*;
import java.util.Arrays;
public class Convert {
  public static void main(String args[]) {
   System.out.println(Charset.availableCharsets());
   Charset asciiCharset = Charset.forName("US-ASCII");
   CharsetDecoder decoder = asciiCharset.newDecoder();
   byte help[] = {72, 101, 108, 112};
   ByteBuffer asciiBytes = ByteBuffer.wrap(help);
   CharBuffer helpChars = null;
   try {
    helpChars = decoder.decode(asciiBytes);
   } catch (CharacterCodingException e) {
    System.err.println("Error decoding");
    System.exit(-1);
   }
   System.out.println(helpChars);
   Charset utfCharset = Charset.forName("UTF-16LE");
   CharsetEncoder encoder = utfCharset.newEncoder();
   ByteBuffer utfBytes = null;
   try {
    utfBytes = encoder.encode(helpChars);
   } catch (CharacterCodingException e) {
    System.err.println("Error encoding");
    System.exit(-1);
   }
   byte newHelp[] = utfBytes.array();
   for (int i=0, n=newHelp.length; i<n; i++) {
    System.out.println(i + " :" + newHelp[i]);
   }
  }
}

注意:除手工執行編碼和解碼外,您還可以向 java.ioInputStreamReader 和 java.ioOutputStreamWriter 構造函數提供一個字符集,讓它們為您執行轉換工作。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved