栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java关于字符编码以及java字符编码转换

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java关于字符编码以及java字符编码转换

		最近工作中遇到一个编码的问题,在这记录一下我的思考过程,供大家参考。

先来一段测试代码,看完结果之后再说一下我的思考和理解:

  public static void main(String[] args) {


        File tmpFile = new File("test.txt");
        OutputStreamWriter osw = null;
        InputStreamReader isr = null;
        try {
            Boolean result = tmpFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(tmpFile);
            osw = new OutputStreamWriter(fos, "UTF-8");
            osw.write("helloword,中国深圳,龙岗区");
            osw.flush();

            FileInputStream fis = new FileInputStream(tmpFile);
            isr = new InputStreamReader(fis, "GBK");
            StringBuffer sb = new StringBuffer();
            while (isr.ready()) {
                sb.append((char) isr.read());
            }
            System.out.println("-----------------------------------------------------------------------");
            System.out.println(sb.toString());
            System.out.println(new String(sb.toString().getBytes("GBK"),"UTF-8"));
            System.out.println("-----------------------------------------------------------------------");

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                    if(osw != null) osw.close();
                    if(isr != null) isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

    }

执行结果:

-----------------------------------------------------------------------
helloword,涓浗娣卞湷,榫欏矖鍖�
helloword,中国深圳,龙岗�?
-----------------------------------------------------------------------

我故意用GBK去解析UTF-8写入的字符串,读出来的字符串肯定会乱码,是的,这个很好理解,关键说第二条打印的数据:
我将读出来的UTF-8字符串再转成GBK的二进制,然后再装成UTF-8的字符串,发现和我最初的字符串并不相同!
其实,这是因为转成"helloword,涓浗娣卞湷,榫欏矖鍖�"的GBK字符串时,数据以及在翻译的过程中被破坏了,“�”其实就是由于在GBK中找不到对应的含义的字符才生成的一个通用字符,你想想,此时再反过来操作一遍,肯定是得不到原来的字符串了。当然这种情况也不是一定会发生,这个要看具体的两个编码。

关于编码的认知

所有在计算机中展示出来的数据都是计算机通过固定的编码,将二进制数据转换成人类能够看的懂的字符,在人与计算机交互的过程中,编码(Unicode,UTF-8,GBK等)就相当于一个中介,准确点说应该是翻译。

关于编码转换

在JVM中,字符串String是没有编码的概念的,因为JVM是统一使用的Unicode进行String的计算和存储的,这样才能保证相同的字符串计算出来的二进制是相同的;
所以,在java中,相同的字符串,要实现A到B编码的转换,过程是这样的:二进制先按照A编码转换成String(unicode),然后String再按照B编码转换成二进制。
这里其实就涉及Java中两个不得不说的API:
1、String.getBytes(“GBK”) :将String转换成指定编码的二进制数组。
2、new String(二进制数组,“GBK”) :将二进制数组按照指定的编码解析成字符串。

结论

1、对于某一个二进制数组[]byte,如果不知道它的原生编码,计算机是没办法正确解析它的,因为计算机不知道要将它解析成什么样子人类才看得懂。
2、对于某一个二进制数组[]byte,如果不知道它的原生编码,是没办法转换成某一种其他的固定编码的(因为翻译出来的String不确定是否正确,与第一个结论相同)。
3、对于某一个二进制数组[]byte,如果知道它的原生编码为A,用非原生编码B对其进行解析之后得到的String C是会存在数据被破坏的风险的,也就是说,此时的字符串C如果再用B编码生成二进制[]byte,然后通过A转换成字符串D,此时,C不一定等于D,也就是说,这个过程不一定可逆,从最上面的代码可以看出。
4、所以,最关键的一条结论来了:为了保证双方数据一致性,双方在读和写的过程中使用的编码一定要一致,用不相同的编码翻译过的数据就不能逆向使用

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605502.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号