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编码原理解析)

        FileOutputStream fileOutputStream =
                new FileOutputStream("module-11\\data\\out.txt");
        fileOutputStream.write(100);
        fileOutputStream.write(35);

        FileInputStream fileInputStream =
                new FileInputStream("module-11\\data\\out.txt");
        System.out.println(fileInputStream.read());// 100
        System.out.println(fileInputStream.read());// 35

先创建了一个out.txt的文件,写入两个字节的内容。因为文件最基本的格式就是01二进制的样子,所以这个out.txt,里面存放的就是100和35的二进制数据。用 binary viewer打开

用binaryViewer打开out.txt,查看里面的二进制数据。可以看到:

64 是16进制数,占一个字节,转化二进制:01100100 刚好是100,

23 是16进制数,占一个字节,转化二进制:00100011 刚好是 35,

这也验证了我刚刚确实在out.txt里存入的100和35是按二进制存储的。

常说的 用UTF-8,GBK编码 打开文件注意是打开文件)是什么意思呢?他们只是读取这基本的二进制数据,不会去改变数据本身。他们根据自己的编码规则,会去读取字节数据,然后把他转化为字符。在这里ASCII编码,就读取了01100100,然后根据ASCII的编码,这个二进制对应的字符就是d,同理,00100011对应字符#。

打开文本文件,肯定是要选编码格式,编码格式不同,打开得到的字符有时候就不同

但是 我们无论以什么编码打开out.txt源文件,得到的二进制数据肯定还是我们刚刚存入的01100100,00100011

FileInputStream fileInputStream =
 new FileInputStream("module-11\\data\\out.txt");
System.out.println(fileInputStream.read());//100
System.out.println(fileInputStream.read());//35

?我们重新读取文件 可以看到,数据源并没有发生改变

?????????反过来,我们创建一个txt文件,然后写入 汉字 “中”,我们保存的时候,可以选择不同的编码保存注意这里是保存文件),编码不同,保存的文件结果,基本也不同(这里的文件结果不同,指的是文件的二进制数据不同),所以这就形成了我们常见的 乱码(用A 编码保存文件,以B编码打开文件)。所以我们保存文件,是用什么编码,那么打开文件一定也要是对应的编码格式打开,否则就形成乱码。

????????

关于Unicode和GBK,UTF-8,UTF-16的关系解释:

Unicode是用来存储全世界的语言的一张映射表,全世界所有的字符都被Unicode编码,GBK,UTF-8,UTF-16是Unicode的实现方式之一。?

看看UTF-8的编码方式,(UTF-8是对Unicode进行编码,看看下面的关系)

????????找了两个Unicode字符,但是好像在很多地方都不支持,表现出复制后为乱码(这里要特别注意,这两个字符虽然是乱码,只是因为软件不支持这两个Unicode 的图像化),分别以UTF-8格式 保存在文本里。

  • 𐆙? ? U+10199

  • 𐆘? ? U+10198
    ?就这样复制了以UTF-8 另存 就行了,然后然后查看二进制文件。

  • 这两个字符只是软件不支持图像化,但是编码依然是UTF-8 的编码,见下图。

假设我们在一个window桌面建立一个 .txt 文件,然后在里面写入文件,这个时候可以保存文件为任意的格式,根据格式的不同,这个文件的二进制的数据也不同,因为编码都是有一定的规则。我们可以想象每一个写入的 字符 都是 U+????? (Unicode码点),然后就是根据不同的编码方式,把这些 字符(或者想象为Unicode码点)转化为01二进制的计算机存储的数据。这个是好理解的。

但是在java里面这个就难理解了,首先在 java内部是用的UTF—16这种编码格式,比如说一个特殊的字符串

"a我𝕆" 首先字符是得要转换为 UTF—16 格式,在这里就是?\u0061\u6211\uD835\uDD46 (\u0061代表这个是一个UTF—16 码元 ),每个 char 都只能存储这一个\u0061 码元,因为这是0x0061(16进制数)有2个字节。𝕆 字符比较特别,2个 UTF—16 码点 才能表示他,所以这个字符要2个char来存储,所以这整个?"a我𝕆" ,的长度为4 ,因为他用了4个 char 存放(但是好像是jdk1.8 后 String类 就不是用 char[] 来存放数据,而是用 byte[] 来做为存储的容器。我们这里还是假设用char[] 来做String的容器,其实用 byte[] 来做容器了,你也可以把它内部当作char[])

插入一条例子

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
new FileOutputStream("module-11\\data\\UTF_8.txt"), StandardCharsets.UTF_8); //其实默认的就是UTF-8编码 格式写入文件
String s = "\u0061\u6211\uD835\uDD46"; // a我𝕆
char[] chars = s.toCharArray();
int i =0;
System.out.println(chars.length);//4
outputStreamWriter.write(chars[3]);
outputStreamWriter.write(chars[2]);
outputStreamWriter.write(chars[1]);
outputStreamWriter.write(chars[0]);
outputStreamWriter.flush();
//  存储的结果: ??我a

第二次顺序存储:
//        System.out.println(chars.length);//4
//        outputStreamWriter.write(chars[0]);
//        outputStreamWriter.write(chars[1]);
//        outputStreamWriter.write(chars[2]);
//        outputStreamWriter.write(chars[3]);
//        outputStreamWriter.flush();
//        //  存储的结果: a我𝕆

write方法 只能每次读入一个 char ,在这里所有的文本在被读入后,会被 重新进行一次转化,就是UTF—16 到 UNicode的转化,这里只能这样理解,才能解释这里两次存储的差异性。

读文件就是反过来,

可以看到二进制的数据,当编码确定就可以直接转化为字符,这里的3个字节,是UTF-8的编码规则

byte[] bytes1 = new byte[3];
bytes1[0] = (byte) 0b11100110;
bytes1[1] = (byte) 0b10001000;
bytes1[2] = (byte) 0b10010001;
String s = new String(bytes1, StandardCharsets.UTF_8);
System.out.println("s = " + s);// s = 我
FileOutputStream fileOutputStream = new FileOutputStream("byte.txt");
fileOutputStream.write(bytes1);
fileOutputStream.flush();//存储的结果也是 “我”

第一次写csdn,不太会,希望能多多包涵,也希望能提点意见

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 13:44:53  更:2022-01-01 13:44:59 
 
开发: 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 7:31:41-

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