Java字符编码问题

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

今天研究了一下,记录下来

中间用的是redis,可以使用任意其他的io替代,一样的

 

Test1

        String s1 = "我要测试";

        String s2 = "I want to test";

        String s3 = "경쟁력, 네이버";

        redis.lpush("testencode", s1);

        redis.lpush("testencode", s2);

        redis.lpush("testencode", s3);

        System.out.println(redis.lpop("testencode"));

        System.out.println(redis.lpop("testencode"));

        System.out.println(redis.lpop("testencode"));

结果:全部正确

注解:Java内部也是unicode,所以如果发送和接受端都是Java写的,无需任何转码(前提是发送和接受端的默认编码一致)

        Java在往I/O发送和从I/O接受的时候会默认转码,一般用系统默认的编码,貌似文档本身的编码格式优先级更高

        所以这里发送到时候转成utf-8,接受时再从utf-8转回unicode,所以没有问题

 

Test2

        String s1 = "我要测试";

        byte[] key = "testencode".getBytes();

        byte[] b1 =  s1.getBytes("gb2312"); //自己转码,而非默认转码

        redis.lpush(key, b1);

        System.out.println(new String(redis.lpop(key),"gb2312"));

        //System.out.println(new String(redis.lpop(key)));

结果:正确

注解:由于发送的时候已经转成gb2312,所以接受的时候,必须转回来,如果用默认的(注释掉部分)就会转成默认编码utf-8,就会乱码

 

前面的转码都是在知道原编码的情况下,但有时在接收端无法知道原来的编码,这是就需要detect编码

使用JCharDet,这个的接口写的不好,蛮难用的

参考,http://blog.csdn.net/chenvsa/article/details/7445569

我改了一下,

import org.mozilla.intl.chardet.nsDetector; 
import org.mozilla.intl.chardet.nsICharsetDetectionObserver; 
import org.mozilla.intl.chardet.nsPSMDetector;

public class CharsetDetector{ 
    private boolean found = false; 
    private String result; 
    private int lang = nsPSMDetector.ALL;

    public String[] detectCharset(byte[] bytes) throws IOException 
    { 
        String[] prob; 
        // Initalize the nsDetector() ; 
        nsDetector det = new nsDetector(lang); 
        // Set an observer... 
        // The Notify() will be called when a matching charset is found. 
        det.Init( 
            new nsICharsetDetectionObserver(){    
                public void Notify(String charset) 
                { 
                    found = true; 
                    result = charset; 
                } 
            }); 
        int len = bytes.length; 
        boolean isAscii = true; 
        if (isAscii){ 
            isAscii = det.isAscii(bytes, len); 
        } 
        // DoIt if non-ascii and not done yet. 
        if (!isAscii){ 
            if (det.DoIt(bytes, len, false));                   
        } 
        det.DataEnd(); 
        if (isAscii){ 
            found = true; 
            prob = new String[] {"ASCII"}; 
        } else if (found){ 
            prob = new String[] {result}; 
        } else { 
            prob = det.getProbableCharsets(); 
        } 
        return prob; 
    }

    public String[] detectChineseCharset(byte[] bytes) throws IOException 
    { 
        try{ 
            lang = nsPSMDetector.CHINESE; 
            return detectCharset(bytes); 
        } catch (IOException e){ 
            throw e; 
        } 
    }

使用,

CharsetDetector cd = new CharsetDetector(); 
String[] probableSet = {};

try { 
     probableSet = cd.detectChineseCharset(b1); 
} catch (IOException e) { 
     e.printStackTrace(); 

for (String charset : probableSet) 

    System.out.println(charset); 
}


本文章摘自博客园,原文发布日期:2014-05-14

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
20天前
|
Java API
如何在 Java 中动态地添加字符编码支持
本文介绍了在Java中动态添加字符编码支持的方法,通过使用 Charset 和 CharsetProvider 类,可以扩展 Java 的字符编码能力,实现对更多字符集的支持。
|
20天前
|
Java Maven C++
如何在 Java 中添加新的字符编码支持
在Java中添加新的字符编码支持,可以通过实现java.nio.charset.Charset和CharsetProvider接口来完成。自定义字符集编码后,注册到JVM中即可使用。适用于特定业务场景下的特殊字符集需求。
|
6月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
40 0
|
7月前
|
JSON fastjson 数据库
字符编码导致Rapidjson(腾讯开源的json解析库)到Fastjson(阿里开发的Java json解析库)转换失败的原因分析
最近在客户端的开发的过程中,使用到了RapidJson,公司的开发是客户端和数据库端都由不同的人进行开发,我负责的客户端的逻辑开发(使用c++),开发工具同时使用了VS2017和QT的编译环境,使用QT主要是为了客户端界面开发方便,而使用了VS环境主要是维护公司开发的数据库接口库,这个库的唯一作用就是作为一个中间桥梁,使用Rapidjson将数据库接口的json数据格式解析为结构体数据,从而在客户端界面进行展示,或者接收客户端的数据,使用Rapidjson将其转换为json数据,发送给数据库接口以保存数据使用 。不太明白的可以参考我上一篇文章说明Rapidjson的使用过程-Parse解析数组
148 0
|
自然语言处理 Java 索引
Java中的Unicode字符编码与占用比特位解析
Java中的Unicode字符编码与占用比特位解析
|
存储 Java
java 字符编码转换
java 字符编码转换
156 0
|
存储 小程序 Java
【字符编码】Java字符编码详细解答及问题探讨
 继上一篇写完字节编码内容后,现在分析在Java中各字符编码的问题,并且由这个问题,也引出了一个更有意思的问题,笔者也还没有找到这个问题的答案。也希望各位园友指点指点。
158 0
【字符编码】Java字符编码详细解答及问题探讨
|
存储 Java
【字符编码】Java编码格式探秘
  在分析Comparable和Comparator的时候,分析到了String类的compareTo方法,String底层是用char[]数组来存放元素,在比较的时候是比较的两个字符串的字符,字符用char来存储,此时,突然想到,Java里面的char可以存放中文吗?后来发现是可以的,并且由此也引出了Java中字符的编码格式问题。
126 0
【字符编码】Java编码格式探秘
|
Java API
JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 一.打印流PrintWriter 打印流有PrintWriter和PrintStream,他的特点可以直接操作输.
1071 0
下一篇
无影云桌面