IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java关于字符编码以及java字符编码转换 -> 正文阅读

[Java知识库]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、所以,最关键的一条结论来了:为了保证双方数据一致性,双方在读和写的过程中使用的编码一定要一致,用不相同的编码翻译过的数据就不能逆向使用

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:07:59  更:2021-11-28 11:10:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:39:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码