Java字符串与字符集的基本概念(4)

  通过此例可以看出,从ISO-8859-1字符集转换成Unicode字符集的过程是将字节化字符数据中的每个一个byte类型元素直接保存成一个char类型元素。也就是说下面的代码:


  byte[] bytes = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
  String str = new String(bytes, Charset.forName("ISO-8859-1"));
  byte[] bytes = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
  String str = new String(bytes, Charset.forName("ISO-8859-1"));


  等效于:


   byte[] bytes = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
  char[] tmp = new char[bytes.length];
  for (int i=0; i 
  tmp[i] = (char)bytes[i];
  }
  String str = new String(tmp);
  byte[] bytes = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
  char[] tmp = new char[bytes.length];
  for (int i=0; i 
  tmp[i] = (char)bytes[i];
  }
  String str = new String(tmp);


  需要注意的是,ISO-8859-1到Unicode的转换过程是对编码值为0x00 - 0xFF之间都有效的一种转换。在ISO-8859-1字符集中,0x00-0x1F、0x7F、0x80-0x9F没有定义。我们可以使用其中几个无效编码进行测试:


  view plaincopy to clipboardprint?
  public static void main(String[] args) {
  // 无效的ISO-8859-1编码
  byte[] bytes = { (byte) 0x00, (byte) 0x1A, (byte) 0x7F, (byte) 0x93 };
  String str = new String(bytes, Charset.forName("ISO-8859-1"));
  printBytes("ISO-8859-1编码:", str.getBytes(Charset.forName("ISO-8859-1")));
  printBytes("UNICODE编码:", str.getBytes(Charset.forName("UNICODE")));
  }
  public static void printBytes(String title, byte[] data) {
  // 同上
  }
  public static void main(String[] args) {
  // 无效的ISO-8859-1编码
  byte[] bytes = { (byte) 0x00, (byte) 0x1A, (byte) 0x7F, (byte) 0x93 };
  String str = new String(bytes, Charset.forName("ISO-8859-1"));
  printBytes("ISO-8859-1编码:", str.getBytes(Charset.forName("ISO-8859-1")));
  printBytes("UNICODE编码:", str.getBytes(Charset.forName("UNICODE")));
  }
  public static void printBytes(String title, byte[] data) {
  // 同上
  }


  上例的输出结果为:


 ISO-8859-1编码:
  0x00 0x1A 0x7F 0x93


  UNICODE编码:


 0xFE 0xFF 0x00 0x00 0x00 0x1A 0x00 0x7F 0x00 0x93


  根据这一特点,我们可以总结出最后一个要点:

  利用ISO-8859-1字符集,我们可以将任何一个字节数组无损保存到字符串对象中。

  也就是说,可以利用这一特点将字节化字符数据的原始字节数据(而不是经过Unicode字符集转换之后的数据)直接保存在字符串对象中。反之也可以从一个经过ISO-8859-1编码的字符串对象中取出原始字节数据。例如:


   view plaincopy to clipboardprint?
  public static void main(String[] args) {
  byte[] utf8Bytes = {(byte)0xE4, (byte)0xB8, (byte)0xAD, (byte)0xE5, (byte)0x9B, (byte)0xBD};
  printBytes("原始字节流:" , utf8Bytes);
  // ISO-8859-1编码过程
  // 保存原始字节数据流(不经过Unicode编码)到字符串对象
  String isoStr = new String(utf8Bytes, Charset.forName("ISO-8859-1"));
  // ISO-8859-1解码过程
  // 从字符串对象中取得与utf8Bytes内容完全相等的原始字节数据流
  byte[] tmp = isoStr.getBytes(Charset.forName("ISO-8859-1"));
  printBytes("转换字节流:" , tmp);
  }
  public static void printBytes(String title, byte[] data) {
  // 同上
  }
  public static void main(String[] args) {
  byte[] utf8Bytes = {(byte)0xE4, (byte)0xB8, (byte)0xAD, (byte)0xE5, (byte)0x9B, (byte)0xBD};
  printBytes("原始字节流:" , utf8Bytes);
  // ISO-8859-1编码过程
  // 保存原始字节数据流(不经过Unicode编码)到字符串对象
  String isoStr = new String(utf8Bytes, Charset.forName("ISO-8859-1"));
  // ISO-8859-1解码过程
  // 从字符串对象中取得与utf8Bytes内容完全相等的原始字节数据流
  byte[] tmp = isoStr.getBytes(Charset.forName("ISO-8859-1"));
  printBytes("转换字节流:" , tmp);
  }
  public static void printBytes(String title, byte[] data) {
  // 同上
  }


  上例的输出结果为:

  原始字节流:


 0xE4 0xB8 0xAD 0xE5 0x9B 0xBD


  转换字节流:


  0xE4 0xB8 0xAD 0xE5 0x9B 0xBD


  这种通过字符串对象保存原始字节数据的方法被很多地方所使用。最常见的就是Java WEB应用中Web服务器对来自于服务器的表单数据的处理,关于这方面的详细说明请参考 如何解决Java WEB应用中的乱码问题

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpdjy.html