当前位置:首页 >> 其它课程 >>

(转)java byte与char、String互转原理


(转)java byte 与 char、String 互转原理 2009-10-21 19:22 转:http://www.cnblogs.com/bluespot/archive/2008/10/23/1318155.html 一、字节和 unicode Java 内核是 unicode 的,就连 class 文件也是,但是很多媒体,包括文件/流的保存方式是使用字节流 的。因此

Java 要对这些字节流经行转化。 char 是 unicode 的,而 byte 是字节。Java 中 byte/char 互 转的函数在 sun.io 的包中间有。其中 ByteToCharConverter 类是中调度,可以用来告诉你,你用的 convertor。其中两个很常用的静态函数是: public static ByteToCharConverter getDefault(); public static ByteToCharConverter getConverter(String encoding);

如果你不指定 converter,则系统会自动使用当前的 encoding,gb 平台上用 gbk,en 平台上用 8859_1。 byte ——〉char: "你"的 gb 码是:0xc4e3 ,unicode 是 0x4f60 String encoding = "gb2312"; byte b[] = {(byte)'\u00c4',(byte)'\u00e3'}; ByteToCharConverter converter = ByteToCharConverter.getConverter(encoding); char c[] = converter.convertAll(b); for (int i = 0; i < c.length; i++) { System.out.println(Integer.toHexString(c[i])); } 结果是什么?0x4f60 如果 encoding ="8859_1",结果又是什么?0x00c4,0x00e3

如果代码改为: byte b[] = {(byte)'\u00c4',(byte)'\u00e3'}; ByteToCharConverter converter = ByteToCharConverter. getDefault(); char c[] = converter.convertAll(b); for (int i = 0; i < c.length; i++) { System.out.println(Integer.toHexString(c[i])); }

结果将又是什么? 这就要根据平台的编码而定。 char ——〉byte: String encoding = "gb2312"; char c[] = {'\u4f60'};

CharToByteConverter converter = CharToByteConverter.getConverter(encoding); byte b[] = converter.convertAll(c); for (int i = 0; i < b.length; i++) { System.out.println(Integer.toHexString(b[i])); } 结果是什么?0x00c4,0x00e3 如果 encoding ="8859_1",结果又是什么?0x3f 如果代码改为 String encoding = "gb2312"; char c[] = {'\u4f60'}; CharToByteConverter converter = CharToByteConverter.getDefault(); byte b[] = converter.convertAll(c); for (int i = 0; i < b.length; i++) { System.out.println(Integer.toHexString(b[i])); }

结果将又是什么?还是根据平台的编码而定。 很多中文问题就是从这两个最简单的类派生出来的。而却有很多类不直接支持把 encoding 输入,这给 我们带来诸多不便。很多程序难得用 encoding 了,直接用 default 的 encoding,这就给我们移植带来 了很多困难。 二、utf-8 utf-8 是和 unicode 一一对应的,其实现很简单: 7 位的 unicode: 0 _ _ _ _ _ _ _ 11 位的 unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _ 16 位的 unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 21 位的 unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _

大多数情况是只使用到 16 位以下的 unicode: "你"的 gb 码是:0xc4e3 ,unicode 是 0x4f60 0xc4e3 的二进制: 1100 ,0100 ,1110 ,0011

由于只有两位我们按照两位的编码来排,但是我们发现这行不通,因为第7位不是 0 因此,返回"?" 0x4f60 的二进制: 0100 ,1111 ,0110 ,0000 我们用 utf-8 补齐,变成: 1110 ,0100 ,1011 ,1101 ,1010 ,0000 e4--bd-- a0

于是返回:0xe4,0xbd,0xa0。

三、string 和 byte[] string 其实核心是 char[],然而要把 byte 转化成 string,必须经过编码。string.length()其实就是 char 数组的长度,如果使用不同的编码,很可能会错分,造成散字和乱码。例如: String encoding = “”; byte [] b={(byte)'\u00c4',(byte)'\u00e3'}; String str=new String(b,encoding);

如果 encoding=8859_1,会有两个字,但是 encoding=gb2312 只有一个字这个问题在处理分页是经常发 生。 四、Reader,Writer / InputStream,OutputStream Reader 和 Writer 核心是 char,InputStream 和 OutputStream 核心是 byte。但是 Reader 和 Writer 的 主要目的是要把 char 读/写 InputStream/OutputStream。例如: 文件 test.txt 只有一个"你"字,0xc4,0xe3 String encoding = "gb2312"; InputStreamReader reader = new InputStreamReader(new FileInputStream( "text.txt"), encoding); char c[] = new char[10]; int length = reader.read(c); for (int i = 0; i < length; i++) { System.out.println(c[i]); }

结果是什么?是"你"。如果 encoding ="8859_1",结果是什么?"??"两个字符,表示不认识。反过来的 例子自己做。 五、我们要对 Java 的编译器有所了解: Javac ?encoding

我们常常没有用到 encoding 这个参数。其实 encoding 这个参数对于跨平台的操作是很重要的。如果没 有指定 encoding,则按照系统的默认 encoding,gb 平台上是 gb2312,英文平台上是 iso8859_1。Java 的编译器实际上是调用 sun.tools.Javac.main 的类,对文件进行编译,这个类有 compile 函数中间有 一个 encoding 的变量,-encoding 的参数其实直接传给 encoding 变量。 编译器就是根据这个变量来读取 Java 文件的,然后把用 utf-8 形式编译成 class 文件。例子代码: String str = "你";

FileWriter writer = new FileWriter("text.txt"); write.write(str); writer.close(); 如果用 gb2312 编译,你会找到 e4 bd a0 的字段 ; 如果用 8859_1 编译, 00c4 00e3 的二进制: 0000,0000 ,1100,0100 ,0000,0000 ,1110,0011 因为每个字符都大于 7 位,因此用 11 位编码: 1100,0001,1000,0100,1100,0011,1010,0011 c1-- 84-- c3-a3 你会找到 c1 84 c3 a3

但是我们往往忽略掉这个参数,因此这样往往会有跨平台的问题: 样例代码在中文平台上编译,生成 zhclass 样例代码在英文平台上编译,输出 enclass (1) zhclass 在中文平台上执行 ok,但是在英文平台上不行 (2) enclass 在英文平台上执行 ok,但是在中文平台上不行 原因是: (1) 在中文平台上编译后,其实 str 在运行态的 char[]是 0x4f60, 在中文平台上运行,filewriter 的 缺省编码是 gb2312,因此 chartobyteconverter 会自动用调用 gb2312 的 converter,把 str 转化成 byte 输入到 fileoutputstream 中,于是 0xc4,0xe3 放进了文件。但是如果是在英文平台下, chartobyteconverter 的缺省值是 8859_1, filewriter 会自动调用 8859_1 去转化 str,但是他无法解释, 因此他会输出"?" (2) 在英文平台上编译后,其实 str 在运行态的 char[]是 0x00c4 0x00e3, 在中文平台上运行,中文无 法识别, 因此会出现??; 在英文平台上, 0x00c4-->0xc4,0x00e3->0xe3, 因此 0xc4,0xe3 被放进了文件。 六、其它原因: <%@ page contentType="text/html; charset=GBK" %>

设置浏览器的显示编码,如果 response 的数据是 utf8 编码,显示将是乱码,但是乱码和上述原因还不 一样。 七、发生编码的地方: 1. 从数据库到 Java 程序 byte——〉char 2. 从 Java 程序到数据库 char——〉byte

3. 从文件到 Java 程序 byte——〉char 4. 从 Java 程序到文件 char——〉byte 5. 从 Java 程序到页面显示 char——〉byte 6. 从页面 form 提交数据到 Java 程序 byte——〉char 7. 从流到 Java 程序 byte——〉char 8. 从 Java 程序到流 char——〉byte 可以使用配置过滤器的方法解决中文乱码的: <web-app> <filter> <filter-name>RequestFilter</filter-name> <filter-class>net.golden.uirs.util.RequestFilter</filter-class> <init-param> <param-name>charset</param-name> <param-value>gb2312</param-value> </init-param> </filter> <filter-mapping> <filter-name>RequestFilter</filter-name> <url-pattern>*.Jsp</url-pattern> </filter-mapping> </web-app>

public void doFilter(ServletRequest req, ServletResponse res, FilterChain fChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(); String userId = (String) session.getAttribute("userid"); req.setCharacterEncoding(this.filterConfig.getInitParameter("charset")); // 设置字符集? //实际上是设置了 byte ——〉char 的 encoding try { if (userId == null || userId.equals("")) { if (!request.getRequestURL().toString().matches( ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) { session.invalidate(); response.sendRedirect(request.getContextPath() + "/uirs/logon/logon.Jsp"); } } else { // 看看是否具有信息上报系统的权限

if (!net.golden.uirs.util.UirsChecker.check(userId, "信息上报系统", net.golden.uirs.util.UirsChecker.ACTION_DO)) { if (!request.getRequestURL().toString().matches( ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) { response.sendRedirect(request.getContextPath() + "/uirs/logon/logonController.Jsp"); } } } } catch (Exception ex) { response.sendRedirect(request.getContextPath() +"/uirs/logon/logon.Jsp"); } fChain.doFilter(req, res);


相关文章:
(转)java byte与char、String互转原理
(转)java byte 与 charString 互转原理 2009-10-21 19:22 转:http://www.cnblogs.com/bluespot/archive/2008/10/23/1318155.html 一、字节和 unicode ...
Java 中byte 与 char 的相互转换 Java基础 但是很重要===
Javabyte 与 char 的相互转换 Java基础 但是很重要===_计算机软件及应用_IT/计算机_专业资料。Javabyte 与 char 的相互转换 Java 基础 但是很重要 ...
java byte char 互转
java byte char 互转_计算机软件及应用_IT/计算机_专业资料。首先,byte[]是...char 是 UNICOEDE 字符,为 16 位的整数; String 是个类,一般用来表示字符串...
java中char和byte的转换
javachar和byte转换_计算机软件及应用_IT/计算机_专业资料。javachar ...char 是 UNICOEDE 字符,为 16 位的整数; String 是个类,一般用来表示字符串...
java中char和byte的转换
javachar和byte转换_计算机软件及应用_IT/计算机_专业资料。javachar和...字节型的,一个是整型的; char 是 UNICOEDE 字符,为 16 位的整数; String ...
java中char和byte的转换
javachar和byte转换_计算机软件及应用_IT/计算机_专业资料。首先,byte[]是...char 是 UNICOEDE 字符,为 16 位的整数; String 是个类,一般用来表示字符串...
java中char和byte的转换
javachar和byte转换_计算机软件及应用_IT/计算机_专业资料。? char 转化为 byte: public static byte[] charToByte(char c) { byte[] b = new byte[2...
JAVA里面关于byte数组和String之间的转换问题
JAVA里面关于byte数组和String之间的转换问题_IT/计算机_专业资料。JAVA里面关于byte数组和String之间的转换问题 JAVA 里面关于 byte 数组 String 之间的转换问题 把...
java基本类型与byte数组互相转换
java基本类型与byte数组互相转换_计算机软件及应用_IT/计算机_专业资料。java基本...byte[] charToByteArr(char ch) { byte[] b = new byte[2]; int temp ...
c#中 uint--byte[]--char[]--string相互转换汇总
c#中 uint--byte[]--char[]--string互转换汇总 uint---byte[]---char[]---string 在在做一些互操作的时候往往需要一些类型的相互转换,比如用 c#访问 ...
更多相关标签:
c char byte | java byte char | byte char | byte 转char | char转byte数组 | java byte转char | byte和char的区别 | c byte转char |