`
shappy1978
  • 浏览: 699870 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Kuix乱码问题

    博客分类:
  • J2ME
阅读更多

问题的来源还是前面Kuix国际化的乱码问题,之前没有深究,今天刚好看到了,发现了其中的缘由,先看一篇网上的帖子,讲的就是怎么读取UTF-8:

一、读取Unicode文件
   /**
   * 读取Unicode编码文本文件
   * @param resource String - 文件名
   * @return String - Unicode文本
   */
   public static String read_Uni(String resource) {
   byte word_uni[] = new byte[1024];
   String strReturn = null;
   InputStream is;
   try {
   is = instance.getClass().getResourceAsStream(resource);
   is.skip(2); // 跳过两个字节的文件头
   is.read(word_uni);
   is.close();
   StringBuffer stringbuffer = new StringBuffer("");
   for (int j = 0; j < word_uni.length; ) {
   int l = word_uni[j++];
   int h = word_uni[j++];
   char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));
   stringbuffer.append(c);
   }
   strReturn = stringbuffer.toString();
   } catch (IOException ex) {
   System.out.println(ex);
   } finally {
   is = null;
   }
   return strReturn;
  }
  
  二、读取UTF-8文件
   /**
   * 读取UTF-8编码文本文件
   * @param resource String - 文件名
   * @return String - UTF-8文本
   */
   public static String read_UTF(String resource) {
   byte word_utf[] = new byte[1024];
   String strReturn = null;
   InputStream is;
   try {
   is = instance.getClass().getResourceAsStream(resource);
   is.read(word_utf);
   is.close();
   strReturn = new String(word_utf, "UTF-8");
   } catch (IOException ex) {
   System.out.println(ex);
   }
   return strReturn;
   }

 

再看看property文件的内容

YES=\u662F

 这是GBK编码保存的,这里有点混乱,实机上myeclipse的property编辑器有个bug,编辑器里面保存的属性值全部用系统编码保存,也就是GBK码,如果你自己在源文件中写中文,而且文件属性是UTF-8,保存后是这样的:

YES=\u00CA\u00C7

 变成了4个字节,这种情况下Kuix读到的会是乱码,看Kuix.loadMessages

	private static synchronized void loadMessages(InputStream inStream) throws Exception {

		InputStreamReader inputStream = new InputStreamReader(inStream, "UTF-8");
......
					key = convertString(key);
					value = convertString(value);
					messageTable.put(key, value);

 可以看到试图用UTF-8编码读取文件,而实际上property是用十六进制保存的,所以还需要用convertString做一次转换

	private static String convertString(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);

		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					// Read the xxxx
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								value = (value << 4) + aChar - '0';
								break;
							case 'a':
							case 'b':
							case 'c':
							case 'd':
							case 'e':
							case 'f':
								value = (value << 4) + 10 + aChar - 'a';
								break;
							case 'A':
							case 'B':
							case 'C':
							case 'D':
							case 'E':
							case 'F':
								value = (value << 4) + 10 + aChar - 'A';
								break;
							default:
								// return KuixConstants.DEFAULT_UNKNOWN_I18N_MESSAGE STRING if there is any problem
								return "???";
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't') {
						aChar = '\t';
					} else if (aChar == 'r') {
						aChar = '\r';
					} else if (aChar == 'n') {
						aChar = '\n';
					} else if (aChar == 'f') {
						aChar = '\f';
					}
					outBuffer.append(aChar);
				}
			} else {
				outBuffer.append(aChar);
			}
		}
		return outBuffer.toString();
	}

 关键在这一句outBuffer.append((char) value);它用两个字节做一个汉字了,所以出现乱码,实际上应该参考前面的方法:

   int l = word_uni[j++];
   int h = word_uni[j++];
   char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));

 最后摘一段文章说明UTF-8编码的大小.(http://www.iteye.com/topic/113572)

1、UTF-8用几个字节表示一个汉字? 
这各答案你可能了解,但也可能不了解,我敢打保票一半人会不清楚(包括特意查资料之前的我)。 
了解这个对编程有什么影响? 


以下我把对yoolywu的回答,转为帖子发表,以表重视。 


yollywu的问:
引用
系统有两个子系统,一个是BS的,一个是delphi做的CS,中间的数据传输是通过XML进行传输的。在XML传输的功能实现后,要求对XML进行加密解密.加密解密算法是CS端用delphi写的,然后这边用JAVA写个同样的算法。现在碰到的一个问题是: 
用该算法的时候,CS和BS各自都能够加解密,我这边的过程是这样的。。。。[但最后]中文始终是乱码 
Java代码 
   
       StringBuffer strbuf = new StringBuffer();  
try {  
    FileInputStream in = new FileInputStream(file);  
    int size = 0;  
    byte [] buf = new byte[1024];     
    while ((size=in.read(buf)) != -1) {  
        strbuf.append(new String(buf,0,size));  
    }  
      
} catch (FileNotFoundException e) {  
    // TODO Auto-generated catch block  
    e.printStackTrace();  
} catch (IOException e1) {  
    // TODO Auto-generated catch block  
    e1.printStackTrace();  
}  
      return strbuf;  
           





Qieqie的答: 



以下的代码是错误的: 
Java代码 
StringBuffer strbuf = new StringBuffer();     
...  
 strbuf.append(new String(buf,0,size));    


第一、 
你应该使用ByteArrayOutputStream,将InputStream的字节全部读出来,然后转成byte[]数组,最后在根据你和对方协议规定的字符集合(假设你们规定的是UTF-8,如果没有规定,那么就补充上吧),将byte[]变成String: String theString = new String(bytes, "UTF-8")。 
不加"UTF-8"的new String,将使用Java环境设置的字符集,没有特别设置的情况下也就是操作系统的字符集。这是不可靠的。 

第二、 
不能使用byte[]+StringBuffer:StringBuffer是针对char操作的(String也是)。读取byte时可能刚好把一个多字节的char分成前后两批加入StringBuffer。这样就破坏了char的完整性了。而如果你使用UTF-8编码的中文,你就会中招,导致乱码(其实是因为你的读取是由于byte失去原有顺序导致的,跟一般的乱码还不一样) 
-- 
在UTF-8编码集中,每个汉字使用 3个字符表示! 实践证明: 
1、创建一个UTF-8编码的文件:weare.txt 
2、写入三个字:“我们是” 
3、运行以下代码: 
Java代码 
public class UTF8 {  
  
    public static void main(String[] args) throws IOException {  
        String p = "weare.txt";  
        InputStream in = new FileInputStream(p);  
        int read = in.read(new byte[1204]);  
        System.out.println(read);  
          
    }  
}  

4、你会发现打印出来的是 9 ! 

所以,byte[]+StringBuffer的使用方式是错误的! 

不过可以使用StringBuffer + bufferedReader.readLine(),读出一行行后再加入StringBuffer。 
或者第2楼说的stringbuffer+reader.read(char[])的形式(毕竟错误是由于byte[]导致的,而非StringBuffer) 




参考资料: 

zh.wikipedia.org 写道

UTF-8 使用一至四个字节为每个字符编码。128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。 

 

分享到:
评论

相关推荐

    乱码问题的解决

    "乱码问题的解决" 在 Web 开发中,乱码问题是常见的难题之一。乱码问题的出现主要是由于编码不一致引起的。编码不一致可能出现在多个方面,如页面编码、服务器编码、客户端编码、数据库编码等。在本文中,我们将...

    中文乱码问题分析 自己总结的

    中文乱码问题分析 中文乱码问题是 Java 和 JSP 开发中的一种常见问题,主要是由于 Java 和 JSP 源文件的保存方式是基于字节流的,而编译成 class 文件过程中,使用的编码方式与源文件的编码不一致所致。在 Java ...

    FORM表单中文乱码问题分析与解决

    FORM表单中文乱码问题分析与解决 在 Web 开发中,中文乱码问题是一个常见的问题,尤其是在FORM表单传递参数时。这个问题的根本原因是对中文的编码与解码方式不一致。我们可以理解为对中文的加密与解密的密钥不一致...

    解决JSP中文乱码问题

    解决 JSP 中文乱码问题 解决 JSP 中文乱码问题是一个很常见的问题,在 JSP 开发过程中,经常出现中文乱码的问题,可能一至困扰着大家。下面我们将详细讨论 JSP 中文乱码问题的成因和解决方法。 JSP 中文乱码问题的...

    hadoop中文乱码问题

    【Hadoop中文乱码问题详解】 在大数据处理领域,Hadoop是一个不可或缺的开源框架,它提供了分布式存储(HDFS)和分布式计算(MapReduce)的能力。然而,在处理包含中文字符的数据时,用户可能会遇到中文乱码的问题...

    解决linux下oracle中文乱码问题,添加中文支持

    解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码...

    润乾报表乱码问题

    在信息技术领域,乱码问题是指字符在计算机中由于编码不一致或者不正确而导致的显示错误,通常表现为无法识别的特殊符号或者乱糟糟的方块。润乾报表乱码问题尤其令人头疼,因为它影响了数据的显示和传输,尤其是对于...

    解决Ubuntu和Windows的文件乱码问题

    在使用不同操作系统处理文件时,文件乱码是一个常见问题,尤其是当涉及到Windows和Ubuntu这两种系统时。Windows系统通常使用GBK编码来处理中文,而Ubuntu系统默认使用UTF-8编码,这导致了两者在处理中文文件时出现...

    js出现乱码问题介绍大全

    ### JS出现乱码问题介绍大全 #### 一、引言 在Web开发中,字符编码问题经常困扰开发者,特别是当涉及到不同语言环境时。JavaScript作为前端开发的核心技术之一,在处理字符编码方面同样会遇到各种各样的乱码问题。...

    qt乱码问题解决

    qt乱码问题解决

    设置乱码问题(设置乱码问题)

    ### 设置乱码问题详解 #### 一、理解乱码问题 在进行数据库操作时,可能会遇到数据呈现为不可读字符的现象,这种情况通常被称为“乱码”。出现乱码的原因多种多样,比如字符集设置不一致、编码转换错误等。解决...

    java中文乱码问题详解--- java中文乱码问题详解

    ### Java中文乱码问题详解 #### 一、中文问题的来源与背景 计算机技术发展初期,操作系统主要支持单字节的ASCII字符集。随着全球化进程加快和技术进步,为支持多种语言,尤其是双字节编码的语言(如中文),提出了...

    springboot乱码问题解决方案

    SpringBoot乱码问题解决方案 SpringBoot框架是一款流行的Java Web开发框架,但是在实际开发中,开发者经常会遇到乱码问题,导致项目无法正常运行。为了解决这个问题,本文将详细介绍SpringBoot乱码问题解决方案,并...

    Netty进制转换乱码问题

    在使用Netty进行TCP/IP通信时,我们可能会遇到数据进制转换导致的乱码问题。这个问题通常是由于数据编码不一致或者处理方式不当所引起的。在本文中,我们将深入探讨Netty中的进制转换和字符编码,并提供解决方案。 ...

    乱码解决 乱码解决 乱码解决 乱码解决 乱码解决

    在IT领域,乱码问题是一个常见的困扰,尤其是在处理文本数据时。乱码通常指的是字符显示不正确或无法识别,这可能由于编码格式不匹配、文件损坏、程序设置不当等原因引起。下面将详细讨论乱码产生的原因、解决方案...

    Java开发乱码问题解决方法汇总

    Java开发乱码问题解决方法汇总 Java开发中乱码问题是非常常见的问题之一,而解决这些问题需要具备一定的技术知识和经验。在本文中,我们将总结一些常见的Java开发乱码问题解决方法,希望能够为读者提供帮助。 1. ...

    Linux系统中文乱码解决完整方案

    本文档旨在解决 Linux 系统中文乱码问题,提供了一个完整的解决方案。该问题是由于 Linux 和 Windows 系统下所用户的字符集不同,Linux 系统使用的是 Unicode 字符集,而 Windows 使用的是 GB 字符集所导致的。 在 ...

    解决web项目中出现的乱码问题,很方便

    在开发Web项目时,乱码问题常常困扰着开发者,它涉及到字符编码的处理,这是Web应用中的一个常见但至关重要的问题。本方案提供了一个简洁有效的解决方法,通过一个Java文件和在`web.xml`配置文件中的简单设置,可以...

    解决中文乱码问题

    "解决中文乱码问题" 在Java编程中,中文乱码是一个常见的问题。为了解决这个问题,我们需要从多个方面入手。首先,我们需要将Eclipse的编码方式设置为UTF-8,以便正确地显示中文字符。其次,我们需要在浏览器中将...

    使用ODBC中文乱码问题.docx

    ODBC中文乱码问题解决方案 在使用ODBC对数据库进行中文字符串插入时,经常会遇到中文字符串显示乱码的问题。本文将通过对该问题的分析和解决方案,帮助读者更好地理解ODBC中文乱码问题的成因和解决方法。 一、问题...

Global site tag (gtag.js) - Google Analytics