Step By Step(Java 国际化篇)(七)

2014-11-24 02:47:47 · 作者: · 浏览: 13
arset.forName("UTF-16BE"), Charset.forName("UTF-8"),
17 Charset.forName("US-ASCII"), Charset.forName("ISO-8859-1") };
18 for (int i = 0; i < csets.length; i++) {
19 System.out.println(csets[i].name() + ":");
20 //编码显示
21 print(csets[i].encode(bb.asCharBuffer()));
22 //解码用于下一次迭代
23 csets[i].decode(bb);
24 bb.rewind();
25 }
26 }
27 }
28 //根据指定的字符集,将数据在CharBuffer和ByteBuffer之间做转换(编码和解码)
29 public static void main(String[] args) throws CharacterCodingException {
30 //由于有中文的存在,因此这里需要是用UTF-8的字符集,如果使用其他
31 //的西方字符集会导致encode抛出异常。
32 Charset charset = Charset.forName("UTF-8");
33 // An engine that can transform a sequence of bytes in a specific
34 // charset into a sequence of sixteen-bit Unicode characters.
35 // from byte to unicode
36 CharsetDecoder decoder = charset.newDecoder();
37 // An engine that can transform a sequence of sixteen-bit Unicode
38 // characters into a sequence of bytes in a specific charset.
39 // from unicode to byte
40 CharsetEncoder encoder = charset.newEncoder();
41 ByteBuffer bbuf = ByteBuffer.allocate(1024);
42 CharBuffer cbuf = CharBuffer.allocate(1024);
43 String tmp = "HelloWorld123你好";
44 cbuf.put(tmp);
45 cbuf.flip();
46 //或者直接给CharBuffer赋值,如:
47 //cbuf = CharBuffer.wrap("HelloWorld123你好");
48 //该语句相当于上面3条语句的功能。
49
50 //注:在encode内部已经调用了bbuf.flip(),如果外部重复调用,会导致后面的
51 //decode返回空值。
52 bbuf = encoder.encode(cbuf);
53 byte[] buf = bbuf.array();
54 String s = new String(buf,charset);
55 System.out.println("ByteBuffer = " + s);
56 //注:在decode内部已经调用了cbuf.flip(),如果外部重复调用,会导致后面
57 //打印空值。
58 cbuf = decoder.decode(bbuf);
59 System.out.println("CharBuffer = " + cbuf.toString());
60 }
8. 资源包:
经常会遇到这样的情形,我们应用程序中的大量字符串信息需要被翻译成各种不同的语言,如英文、德文等。我们常用的方式是自定义包含各种不同语言信息的文件,并通过文件名来标识其所属的语种。我们的应用程序在根据当前不同的locale来选择不同的语言资源文件。在Windows的MFC中,是通过一种被称为字符表的资源来存储这些信息的。在Java中,JDK同样提供了其自身的支持--资源包。
和我们想象的一样,JDK也是通过将不同语言的字符串信息存放在不同的资源文件中,同时也定义了语言资源文件的文件命名规则:包名_语言_国家,如MyProgramStrings_de_DE。如果locale = new Locale("de","DE");该资源文件将会被加载。既然Java已经为我们提供了这样的方法,我们还是应该充分的利用这一规则。事实上,和我们预想的非常相似,该资源文件也是以键值对的方式存储资源信息的,如下面的德文和英文资源文件:
File: MessageBundle_en_US.properties
planet = Mars
template = At {2,time,short} on {2,date,long}, we detected {1,number,integer} spaceships on the planet {0}.

File: MessageBundle_de_DE.properties
planet = Mars
template = Um {2,time,short} am {2,date,long} haben wir {1,number,integer} Raumschiffe auf dem Planeten Mars entdeckt.
将以上两个文件copy到工程的bin目录下,再执行下面的示例代码:
1 public class MyTest {
2 static void displayMessage(Locale currentLocale) {
3 System.out.println("currentLocale = " + currentLocale.toString());
4 //getBundle的第一个参数是资源文件的前缀,后缀则根据Locale来定义。
5 ResourceBundle messages = ResourceBundle.getBundle("MessageBundle",currentLocale);
6 Object[] messageArguments = { messages.getString("planet"),
7 new Integer(7), new Da