关于java中的编码问题
ok,今天搞了一天都在探索java字符的编码问题.十分头疼.最后终于得出几点:
1.网上有很多博客说判断一个String的编码的方法是通过如下代码;但其实这个代码完全是错的,用一种编码decode后,再encode,最后的结果是完全一样的.所以下面这个代码,不管用什么编码方式,结果都是true.
- String encode = "GB2312";
- try {
- if (str.equals(new String(str.getBytes(encode), encode))) {
- String s = encode;
- return s;
- }
- } catch (Exception exception) {
- }
- encode = "ISO-8859-1";
- try {
- if (str.equals(new String(str.getBytes(encode), encode))) {
- String s1 = encode;
- return s1;
- }
- } catch (Exception exception1) {
- }
2.接下来我要说一下我通过实验的出来的结论:java String中的编码方式其实是unicode编码,也就是utf-16编码.当然看到网上很多说法说unicode编码和utf-16编码不一样,但是通过在java中的测试,utf-16编码就是unicode编码,测试代码如下;
System.out.println(StandardCharsets.UTF_16.aliases()); //这个的输出结果是:[utf16, UnicodeBig, UTF_16, unicode]
3.我是怎么得到String中的编码都是unicode编码的:
首先我看了Charset.encode()和Charset.decode()这俩个方法,这俩个方法其实就是在将数据在特定的编码与unicode编码之间转换:将使用某种特定编码的byte流decode成
unicode编码的char[],那可以想象,这个转换其实是彻底的改变了byte流的数据,也就是直接按照编码之间的映射关系,对byte流直接做了修改.然后decode的原理相同,只是方向相反,将
unicode编码的数据直接修改,转换成了某种特定的编码所编码过后的数据.据此可以判断,java在识别char的时候,其实就是按照unicode的编码方式来识别byte流的.
再然后我粗略的看了一下String的构造函数还有getBytes函数的源码,当然源码真的十分复杂,看起来很费劲,所以我只是粗略的看了个大概,然后就可以想象其中的原理了.首先在
在构造String的时候,我们传进去了一个特定的Charset,然后看到在构造函数里调用了这个函数的encode方法,对byte[]进行的encode操作,当然,按照上面所说的,encode操作其实就是将某
种特定编码的byte数据转换成了unicode编码的数据.所以说,String中的编码其实全部都是unicode编码.
然后我看了一下getbytes函数的源码,同样,在这个函数里调用了charset的decode方法,将String中的char[]转换成了特定编码的byte[].那这也进一步证明了String中的数据
确实是由unicode编码编码的.
4.最后把这个原理用在实践中有什么用处呢.当我们从外部读入数据时,不管是读文件还是从网络流中读数据,当然如果直接按数据流一样读入后,读入的数据还保持着原来的编码方式,但如果我
们想把数据放入char[]中打印出来或进行字符处理的话,就会出错.所以要想进行字符操作,就要指定数据源的编码类型,然后将数据重新进行编码.
5.如何输出特定编码方式的数据.其实这个很简单,如果我们的处理后的数据的编码方式就是我们想要的编码方式的话,直接输出就好了.但如果不是的话,可以先把它转成unicode编码,然后再
转成我们想要的编码的byte[]流,然后直接输出去.在转换编码的时候,不建议直接使用Charset中的decode和encode,因为返回的buffer往往都比实际的数据要大,根据源码,我看到在返回buffer
的时候,并没有对buffer进行trim操作.建议使用String的getBytes方法.通过看源码,发现在源码中有trim的操作.长度是通过decode来返回的.decode的具体实现还没有
看完.
关于java中的编码问题的更多相关文章
- 理清Java中的编码解码转换
1.字符集及编码方式 概括:字符编码方式及大端小端 详细:彻底理解字符编码 可以通过Charset.availableCharsets()获取Java支持的字符集,以JDK8为例,得到其支持的字符集: ...
- java中的编码和编码格式问题
看来问的人和回答的人都不一定清楚什么是“编码和编码格式”,以及如何理解“java中字符串的编码”;首先明确几点: unicode是一种“编码”,所谓编码就是一个编号(数字)到字符的一种映射关系,就仅仅 ...
- java基础---->java中字符编码问题(一)
这里面对java中的字符编码做一个总结,毕竟在项目中会经常遇到这个问题.爱不爱都可以,我怎样都依你,连借口我都帮你寻. 文件的编码格式 一.关于中文的二进制字节问题 public static Str ...
- JAVA中的编码分析
在实际编程中可以不用关注JVM中使用的是什么编码,而只需要关注自己输出需要采用的编码,JVM会根据你设置的编码正确操作. 1.String采用的是什么编码? 很多厂家根据规范实现了JVM,JVM只说明 ...
- java中字符串编码转换
Java 正确的做字符串编码转换 字符串的内部表示? 字符串在java中统一用unicode表示( 即utf-16 LE) , 对于 String s = "你好哦!"; 如果源码 ...
- Java中字符编码和字符串所占字节数 .
首 先,java中的一个char是2个字节.java采用unicode,2个字节来表示一个字符,这点与C语言中不同,C语言中采用ASCII,在大多数 系统中,一个char通常占1个字节,但是在0~12 ...
- java 中的编码
1.1字节=8位,1024字节=1KB2.16进制0x12345678,其二进制为00010010 00110100 01010110 01111000共4字节3.字节序:两个或多个字节存放的先后顺序 ...
- 一文解开java中字符串编码的小秘密
目录 简介 Unicode的发展史 Unicode详解 UTF-8 UTF-16 UTF-32 Null-terminated string 和变种UTF-8 简介 在本文中你将了解到Unicode和 ...
- Java中的编码
package coreJava; import javax.swing.plaf.synth.SynthSpinnerUI; public class EncodeDemo { public sta ...
随机推荐
- vim 的配置文件(.vimrc)
linux 下面的root的主目录中新建.vimrc配置文件,配置文件注析方式为“,不是#: 如: "显示行号 set number set ruler
- codeforces 54A
题意:收到礼物的规则为每个假日必收到一份礼物,每K天里至少收到一份礼物,求出N天中收到的礼物的最小数量. 思路:将N天根据假日所在天数分为一段段,当假日与假日之间间隔天数hol[i]>-hol[ ...
- Linux - xshell上传文件报错乱码
xshell上传文件报错乱码,解决方法 rz -be 回车 下载sz filename
- SQL嵌套子查询和相关子查询的执行过程有什么区别(推荐)
SQLServer子查询可以分为 相关子查询 和 嵌套子查询 两类.前提, 假设Books表如下: 类编号 图书名 出版社 价格 ----------------------------------- ...
- 初学Linux笔记
自动获取IP地址的局域网中,用的是DHCP服务器
- 获取window状态栏和标题栏的高度
1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFram ...
- SQL Server 2008可以安装在win7 64位的系统上吗?
可以安装的.SQL 支持32和64位.安装时它自动选择的.下载时注意是完整安装包. SQLFULL_CHS 2008.iso大小:3.28G 已经过百度安全检测,放心下载
- Python语言及其应用 第2章
- ffmpeg处理RTMP流媒体的命令和发送流媒体的命令(UDP,RTP,RTMP)
将文件当做直播送至live ffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/live/streamName re限制输出速率, ...
- Agc003_E Sequential operations on Sequence
传送门 题目大意 $1,2...n,n$个数从小到大排列,有$m$此操作,每次操作给定一个参数$x$,将当且数列作为循环节无限地展开下去,再取前$x$个作为新的数列,求最终的数列每个数出现的次数. $ ...