Java IO(01) 编码问题(一)
来源:互联网 发布:cla 知乎 编辑:程序博客网 时间:2024/06/14 00:54
IO是Java中的一块比较重要的知识,在日常开发中应用广泛,现对Java IO知识进行整理归纳。
在IO之前呢,用几篇文章介绍一下Java中的编码以及File类的基本使用。本篇文章先来简单介绍编码。
为了更直观的解释各种编码以及对他们进行比较我们用几个简单的例子来说明。
代码1
/** * 测试不同的编码格式,为方便显示,将字节序列以16进制形式显示,并且输出只显示有效的低8位 * 具体方式是Integer.toHexString(byte[n] & 0xff) */public class Encode { public static void main(String[] args) throws Exception{ String s = "测试ABC"; //使用IDE默认的编码格式进行字节序列转换,这里的默认编码方式是"utf-8" byte[] b = s.getBytes(); System.out.print("默认utf-8编码:"); for(byte bt : b) { System.out.print(Integer.toHexString(bt & 0xff) + " "); } }}运行结果:
默认utf-8编码:e6 b5 8b e8 af 95 41 42 43
上面这段代码中字符串s中包含了中英文的内容,下面仍旧用这个字符串进行举证。通过上面这个例子可以看出来字符串“测试ABC”进行了字节序列转换后变成了一串二进制,我们用十六进制的形式将其输出显示,最终运行结果如上。这段字符串占据了9个字节,一个汉字用三个字节表示,一个英文字符用一个字节表示。s.getBytes()可以看出,我们没有设置任何编码格式,使用的IDE默认的编码格式进行字节序列转换,这里默认的编码格式是“utf-8”格式。
代码2
/** * 测试不同的编码格式,为方便显示,将字节序列以16进制形式显示,并且输出只显示有效的低8位 * 具体方式是Integer.toHexString(byte[n] & 0xff) */public class Encode { public static void main(String[] args) throws Exception{ String s = "测试ABC"; //显性地设置"utf-8"编码,由于IDE默认也是该编码方式,所以输出结果应该相同 byte[] b2 = s.getBytes("utf-8"); System.out.print("显性设置utf-8编码: "); for (byte bt : b2){ System.out.print(Integer.toHexString(bt & 0xff) + " "); } }}运行结果:
显性设置utf-8编码: e6 b5 8be8 af 95 41 42 43
代码2和代码1的区别就是s.getBytes("utf-8"),这样的更明显地对字节序列转换地编码格式做出了要求,这里设置成“utf-8”格式,从结果上看和代码1的运行结果没有任何区别,实际上本来也不会有区别,这里也证明了默认的编码格式是“utf-8”。
代码3
/** * 测试不同的编码格式,为方便显示,将字节序列以16进制形式显示,并且输出只显示有效的低8位 * 具体方式是Integer.toHexString(byte[n] & 0xff) */public class Encode { public static void main(String[] args) throws Exception{ String s = "测试ABC"; //进行"gbk"格式的字节序列转换 byte[] b1 = s.getBytes("gbk"); System.out.print("gbk编码:"); for (int i = 0; i < b1.length ; i++) { System.out.print(Integer.toHexString(b1[i] &0xff) + " "); } }}
运行结果:
gbk编码:b2 e2ca d4 41 4243
代码3换了一种编码格式,也是我们经常见到的编码格式“gbk”,可以看出来它与“utf-8”编码格式的区别,“gbk”编码中文字符占两个字符,英文占一个字符,所以这段字符串使用这种编码就占据了7个字节。
代码4
/** * 测试不同的编码格式,为方便显示,将字节序列以16进制形式显示,并且输出只显示有效的低8位 * 具体方式是Integer.toHexString(byte[n] & 0xff) */public class Encode { public static void main(String[] args) throws Exception{ String s = "测试ABC"; //java属于双字节编码,一个字符占两个字节,这种编码格式就是"utf-16be" byte[] b3 = s.getBytes("utf-16be"); System.out.print("java双字节utf-16be编码:"); for (byte bt : b3){ System.out.print(Integer.toHexString(bt &0xff) + " "); } }}运行结果:
java双字节utf-16be编码:6d 4b8b d50 410 420 43
代码4展示了java的双字节编码,根据运行结果可以看出,无论中文还是英文,都占据了两个字节,这就是“utf-16be”双字节编码。
代码5
/** * 测试不同的编码格式,为方便显示,将字节序列以16进制形式显示,并且输出只显示有效的低8位 * 具体方式是Integer.toHexString(byte[n] & 0xff) */public class Encode { public static void main(String[] args) throws Exception{ String s = "测试ABC"; //java属于双字节编码,一个字符占两个字节,这种编码格式就是"utf-16be" byte[] b3 = s.getBytes("utf-16be"); System.out.print("java双字节utf-16编码:"); for (byte bt : b3){ System.out.print(Integer.toHexString(bt &0xff) + " "); }/** * 当一个 字节序列想变成字符串,那么字节序列是什么编码格式, * 则转换成字符串也要用这种编码形式,否则就会出现乱码的情况 */ //按照原编码格式"utf-16be"进行转换 String s3 = new String(b3,"utf-16be"); System.out.println(); System.out.println("utf-16be进行转换:"+s3); //"utf-16be"编码格式的字节序列使用IDE默认的"utf-8"格式进行转换结果会乱码 String s4 = new String(b3); System.out.println("使用IDE默认的utf-8格式进行转换:"+s4); }}运行结果:
java双字节utf-16be编码:6d 4b 8b d5 0 41 0 42 0 43
utf-16be进行转换:测试 ABC
使用IDE默认的utf-8格式进行转换:mK�� A B C代码5表示的是将经过“utf-16be"编码格式后生成的字节序列进行字符串的转换,运行结果可以看出来,通过转换成字节序列的编码方式”utf-16be“进行转换的结果和源字符串相同,而通过IDE自身默认的”utf-8“编码方式进行转换,则无法还原原字符串。所以当字节序列想变回字符串,那么字节序列是什么编码格式,则转换成字符串也要用这种编码形式,否则就会出现乱码的情况。
通过以上五段代码,对编程中的编码问题是不是有了一些概念。其实文本文件本身存放就是字节序列,而且可以是任意编码形式的字节序列。需要注意的是,假如我在中文机上创建一个文本文件,这个文本文件只能够识别ANSI这种编码格式的字节序列,这里尤其强调是创建的文本文件,加入我从它处复制到中文机上一个文本文件,这个文本文件是不需要必须是ANSI编码格式的,可以是任意编码形式的文本文件,当复制到中文机上的时候,可以自动完成识别。上面整段话不太好理解,只要记住,向中文机复制文件是不需要关心它的编码格式的,但是创建的话,只能是ANSI编码格式下进行创建,如果你创建一个其它格式的,就会出现乱码。
另外还需要关注一点,在Java中,我们可以看到代码1下表示工程下默认的编码格式是utf-8,但是如果在另一个工程中是采用的其它编码格式,两个工程间的文本文件是无法直接复制的,因为无法识别,会出现乱码,当然,如果你直接复制文本内容的话,可以做到自动识别,这是没有问题的。
这几个例子就先说到这里,在《Java IO(01)编码问题(二)》中会更加详细具体介绍编码问题,包括二进制中的一些基础回顾,例如位运算,大小端等。
参考内容:
https://www.imooc.com/video/1832/0
https://zhidao.baidu.com/question/1637850644089866940.html
http://www.cnblogs.com/vhua/p/idea_1.html
- Java IO(01) 编码问题(一)
- java io的编码问题
- java io的编码问题
- java io输出的编码问题
- Java编码问题(IO流/JSP/Properties)
- 黑马程序员-JAVA.IO-字符集编码问题
- Java IO(02) 编码问题(二)
- 13、Java入门—Java IO流之编码问题
- JAVA IO(一)字符集与字符编码简介
- Java IO 字节编码
- Java Io 之 编码
- java IO 字节编码
- Java Web中的编码问题(一)
- JAVA【IO一】IO流
- JAVA IO系列---字符编码
- Java IO _字符编码
- Java IO _字符编码
- Java IO文件编码转换
- Tomcat中ISO-8859-1转UTF-8中文乱码的问题
- 网易云音乐 ubuntu14.04安装包url
- STL-vector的使用 详细说明
- python 添加环境变量后,仍显示python不是内部命令 pycharm注册码
- ElasticSearch及ElasticSearch-head的安装(windows版本)
- Java IO(01) 编码问题(一)
- cannot be cast to org.springframework.web.accept.ContentNegotiationManager
- Android Paint 之 BitmapShader位图的图像渲染器
- 流计算与批量计算的对比
- Mac自定义隐藏或显示文件的快捷键
- Kotlin反射
- python 爬取斗鱼 Ajax动态加载js分页 使用phontomjs无界面浏览器
- 深度学习---基于空间金字塔池化的卷积神经网络物体检测
- Python解惑:整数比较 is ==的比较