论坛首页 入门技术论坛

JAVA转换与编码模式

浏览 2300 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-11  
OO

字符集<o:p></o:p>

<o:p> </o:p>

转换与编码模式<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

java.nio.charset 包中有三个类可以帮助在将旧应用程序迁移到 Java 平台上时进行字符集之间的转换。John Zukowski 将带您了解这三个类并提供一个演示这种功能的示例。<o:p></o:p>

用数字表示
不怕明说,其实计算机只理解数字。但下面这一点可能就没那么明显因为计算机只理解数字,所以它们需要用某种形式把数字值映射为相应的字符,这样才能显示文本。就是这些映射(或 字符集)才使得计算机可以理解文本。例如,就为了这种映射,早期的台式机使用了 ASCII。当一台使用 ASCII 的计算机存储数字 72101108 112 时,它便知道要显示“Help”这个单词,因为在 ASCII 中,数字 72 H 的值、101 e 的值、108 l 的值、112 p 的值。但如果这台计算机是早期的 IBM 大型机(它使用 EBCDIC 而不是 ASCII),“Help”这个单词将用数字 200133147 151 代表。<o:p></o:p>

<o:p> </o:p>

字符集基础知识
在向 Java 语言迁移时, java.nio.charset 包中有三个类帮助进行这种映射: Charset CharsetEncoder CharsetDecoder 。这些类相互配合,这样您就可以先采用一种映射,然后将其转换为另一种映射。在从另一种映射转换为 Java 映射(Unicode)时,您可以使用解码器(decoder)。然后,如果您需要从 Java 映射(Unicode)再转换为另一种映射(或转换回原来那种映射)时,您可以使用编码器(encoder)。您无法用 java.nio.charset 包在两种非 Unicode 格式之间直接转换,但您可以通过一种中间的 Unicode 格式在两种非 Unicode 格式间进行转换。 <o:p></o:p>

在得到一个解码器或编码器之前,您需要获得用于特定映射的 Charset 。例如,US-ASCII 是用于 7 ASCII 字符集的映射的名称。您只需象下面这样把该名称传递到 Charset forName() 方法中即可: <o:p></o:p>

<o:p> </o:p>

Charset charset = <o:p></o:p>

  Charset.forName("US-ASCII");<o:p></o:p>

一旦有了 Charset ,只需按如下所示请求 CharsetDecoder CharsetEncoder <o:p></o:p>

<o:p> </o:p>

CharsetDecoder decoder =<o:p></o:p>

  charset.newDecoder();<o:p></o:p>

CharsetEncoder encoder =  <o:p></o:p>

  charset.newEncoder();<o:p></o:p>

有了解码器和编码器后,您就可以在不同的字符集之间进行转换了,如下所示: <o:p></o:p>

<o:p> </o:p>

  ByteBuffer bytes = ...;<o:p></o:p>

  CharBuffer chars = decoder.decode(bytes);<o:p></o:p>

  bytes = encoder.encode(chars);<o:p></o:p>

当然,如果不确定哪些字符集可用,您需要用下面的语句来询问: <o:p></o:p>

<o:p> </o:p>

SortedMap map = <o:p></o:p>

   Charset.availableCharsets();<o:p></o:p>

然后您将使用特定的解码器把外部字节转换为内部字符。然后,如果需要把数据发送到 Java 代码外,您将使用编码器把内部字符转换为外部字节。至于哪些特定的字符集可用,您的运行时将确定整个字符集。但每个 Java 编程实现都必须支持下列编码: <o:p></o:p>

  • US-ASCII7 ASCII <o:p></o:p>
  • ISO-8859-1ISO 拉丁字母 <o:p></o:p>
  • UTF-88 UCS 转换格式 <o:p></o:p>
  • UTF-16BE16 UCS 转换格式,大尾数法字节顺序 <o:p></o:p>
  • UTF-16LE16 UCS 转换格式,小尾数法字节顺序 <o:p></o:p>
  • UTF-1616 UCS 转换格式,用标记(marker)识别的字节顺序 <o:p></o:p>

然后,不同的平台可能支持特定于该平台的额外字符集(例如,在 Windows 平台上,您会发现它支持 Windows-1252 字符集)。如果您需要支持其他的字符集,您可以创建自己的字符集。请参阅 java.nio.charset.spi 包中的 CharsetProvider API <o:p></o:p>

完整的示例
清单 1 通过转换单词“Help” ASCII 字节数组值(72101108 112)演示了 Java 字符集转换功能。遗憾的是,缺省情况下没有 EBCDIC 编码器,所以我们将把值转换为 UTF-16LE 字符数组(这只是为每个字符的第二个字节添加一个“0”字节)。 <o:p></o:p>

清单 1. 字符集转换示例<o:p></o:p>

<o:p> </o:p>

import java.nio.*;<o:p></o:p>

import java.nio.charset.*;<o:p></o:p>

import java.util.Arrays;<o:p></o:p>

<o:p> </o:p>

public class Convert {<o:p></o:p>

  public static void main(String args[]) {<o:p></o:p>

    System.out.println(Charset.availableCharsets());<o:p></o:p>

    Charset asciiCharset = Charset.forName("US-ASCII");<o:p></o:p>

    CharsetDecoder decoder = asciiCharset.newDecoder();<o:p></o:p>

    byte help[] = {72, 101, 108, 112};<o:p></o:p>

    ByteBuffer asciiBytes = ByteBuffer.wrap(help);<o:p></o:p>

    CharBuffer helpChars = null;<o:p></o:p>

    try {<o:p></o:p>

      helpChars = decoder.decode(asciiBytes);<o:p></o:p>

    } catch (CharacterCodingException e) {<o:p></o:p>

      System.err.println("Error decoding");<o:p></o:p>

      System.exit(-1);<o:p></o:p>

    }<o:p></o:p>

    System.out.println(helpChars);<o:p></o:p>

    Charset utfCharset = Charset.forName("UTF-16LE");<o:p></o:p>

    CharsetEncoder encoder = utfCharset.newEncoder();<o:p></o:p>

    ByteBuffer utfBytes = null;<o:p></o:p>

    try {<o:p></o:p>

论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics