关于Windows下记事本中保存编码的格式问题

Windows下记事本保存文本文件的时候,可以选择不同的编码格式来保存文件,各种编码保存的文件的二进制是不同的,举例说明:

我们在记事本中输入123,选择默认的编码格式,即ANSI,也就是系统默认的编码格式,简体中文版的默认编码格式为GBK,此时我们使用二进制工具打开时,其二进制形式为:

31 32 33

使用Unicode编码保存,实际上,这种称呼是不正确的,Unicode只是表示字符集方案,并不能表示编码方案,windows对Unicode实际上采用的编码方案是UTF-16LE,其会在文本的开头插入小段字节序标识BOM(FFFE),故其二进制为:

FF FE 31 00 32 00 33 00

使用Unicode big endian编码保存,这种称呼也是不正确的,windows实际上采用的编码方案是UTF-16BE,其会在文本的开头插入大端字节序标识BOM(FEFF),故其二进制为:

FE FF 00 31 00 32 00 33

使用UTF-8编码保存,这种称呼也是不正确的,正常UTF-8编码的二进制是没有BOM标识的,而windows上的UTF-8编码的文件时有UTF-8 BOM标识(EF BB BF),故其二进制为:

EF BB BF 31 32 33

下面请看由BOM头引起的问题的例子:

package test;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;public class Test1 {public static void main(String[] args) throws IOException {String myString = "";byte[] bytes = new byte[10];int readCount = 0;try (FileOutputStream outputStream = new FileOutputStream("D:\\test\\hello.txt")) {outputStream.write(new byte[] { -2, -1, 0, 0x31, 0, 0x32, 0, 0x33 });outputStream.flush();outputStream.close();} catch (Exception e) {}try (FileInputStream reader = new FileInputStream("D:\\test\\hello.txt")) {while ((readCount = reader.read(bytes, 0, 10)) != -1) {myString += new String(bytes, 0, readCount, "UTF-16BE");System.out.println(Arrays.toString(bytes));System.out.println(myString);System.out.println(Integer.parseInt(myString));}} catch (Exception e) {e.printStackTrace();}}
}

该例子我们通过程序写入二进制数据:

FE FF 00 31 00 32 00 33

UTF-16BE的方式读入,当我们将读取的字符串转化为数字时,出现错误了,其上面的输出结果如下:

[-2, -1, 0, 49, 0, 50, 0, 51, 0, 0] 123
java.lang.NumberFormatException: For input string: ”123” at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580) at
java.lang.Integer.parseInt(Integer.java:615) at
test.Test1.main(Test1.java:24)

其真正原因就是这个BOM字节序导致的,一般情况下很难发现这个错误,因为输出的字符串就是“123”,与正常的字符串结果看起来并没有什么不同,这时我们应该想到要查下其二进制表示,这样很快就能发现问题了。

最后,关于字节序BOM,上文提到各种不同的编码其字节序不同,实际上BOM是指一个Unicode character,其值为
U+FEFF,但是由于编码方式不同,其表示出来不同的值,但是都是映射到同一个Unicode字符集上了。

The byte order mark (BOM) is a Unicode character, U+FEFF Byte order mark (BOM), whose appearance as a magic number at the start of a text stream can signal several things to a program consuming the text。

代码为证:

package test;import java.util.Arrays;public class Main {public static void main(String[] args) throws Exception {byte[] a = new byte[] { 0xEF - 256, 0xBB - 256, 0xBF - 256 };byte[] b = new byte[] { 0xFE - 256, 0xFF - 256 };byte[] c = new byte[] { 0xFF - 256, 0xFE - 256 };String aString = new String(a, 0, 3, "UTF-8");String bString = new String(b, 0, 2, "UTF-16BE");String cString = new String(c, 0, 2, "UTF-16LE");System.out.println(Arrays.toString(aString.getBytes("UTF-8")));System.out.println(Arrays.toString(bString.getBytes("UTF-8")));System.out.println(Arrays.toString(cString.getBytes("UTF-8")));}
}

输出结果:

[-17, -69, -65]
[-17, -69, -65]
[-17, -69, -65]

关于Windows下记事本中保存编码的格式问题相关推荐

  1. 分析:windows下cmd默认的编码是ASCII编码 ,windows的中文环境下编码是GBK 方法一:在保存输出流保存的时候做一个对文字GBK编码,在输出到文件 如下 [python] view

    分析:windows下cmd默认的编码是ASCII编码 ,windows的中文环境下编码是GBK 方法一:在保存输出流保存的时候做一个对文字GBK编码,在输出到文件 如下 [python] view ...

  2. windows下cmd中命令操作

    windows下cmd中命令: cls清空 上下箭头进行命令历史命令切换 --------------------------------------------------------------- ...

  3. windows下wsl2中的ubuntu和ubuntu系统下docker使用gpu的异同

    windows下wsl2中的ubuntu和ubuntu系统下docker使用gpu的异同 介绍ubuntu系统下配置docker下GPU使用环境的文章很多,本文算是一个比较性梳理. 主要比较一下wsl ...

  4. 基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案

    基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案 最近在研究Java,涉及命令行编译,使用notepad++编辑器,然后使用javac编译: 之前的几个文件没有中文的内容,都没 ...

  5. windows下cmd中输入nvidia-smi显示不是内部或外部命令解决方法!

    windows下cmd中输入nvidia-smi显示不是内部或外部命令解决方法! 我的cuda.cudnn等都是可以正常使用的,只是查看不了显存,在查看了很多博客后下面这个方法亲测有效: 在环境变量的 ...

  6. Windows下打包文件为tar.gz格式

    tar.gz 是linux和unix服务器使用的格式,在windows下的WinRAR.WinZip等主流压缩工具不能压缩成tar.gz格式.万能的"7-ZIP"可以在window ...

  7. Windows下运行jekyll,编码已不再是问题

    很久没更新jekyll了,所以好奇着去官网看了下更新记录,发现如下更新条目(版本1.3.0/2013-11-04发布): Add encoding configuration option (#144 ...

  8. 菜鸟在 windows 下 python 中安装 jupyter 踩坑要点 、被神化的 VsCode

    我平时用不到 python ,更没用过 jupyter ,因此我的 python知识仅限于知道有 python 这么个编程语言,会写个 print("Hello World!!!" ...

  9. Windows下VC++显示UTF-8编码中文

    笔者在Windows下使用C++编写程序接收UTF8字符串会发生中文无法正常在console上显示的问题,故特来解决UTF8字符串如何在VC++上正常显示. 1.问题重现,UTF-8编码下的字符串&q ...

最新文章

  1. php捕获Fatal error错误与异常处理
  2. 三种常见中文内码的转换方法
  3. 区块链BaaS云服务(25)边界智能 IRITA服务
  4. tensorflow tf.data.TextLineDataset()对象 (包含来自一个或多个文本文件的行的“数据集”) 不懂是啥玩意??
  5. 第一阶段_第一部分_工具介绍
  6. 用Fedora发行版本打包RPM,似乎无法对打好的RPM包进行签名?
  7. 实验报告类与对象水井问题_物业设施设备巡检检查对象、周期和频次
  8. java perl5compiler,Java中正则表达式使用方法详解(四)
  9. Android笔记-对称与非对称加密及DH密钥交换
  10. JAVA程序获取Tomcat的运行状态
  11. [C#]Main(String[] args)参数输入问题
  12. 20190605每日一句你的态度决定了你的人生高度
  13. Semantic UI 之 下拉菜单 dropdown
  14. 基于SSM的网上购物系统
  15. 让Excel 只显示有限行和列
  16. 卧底“刷量”卖家,有关微信公众号“刷量”的五个劲爆事实
  17. 戴尔笔记本插入耳机没有反应
  18. js笔记--BOM编程
  19. 《Linux内核分析》期中总结
  20. 怎样修改PDF文档,PDF页面大小怎么设置

热门文章

  1. 只有本科学历的传奇数学家去世了:他打开了通往费马大定理的大门
  2. java之文件上传后需要修复问题(Doc文档,Excel文档等)
  3. 蓝牙Mesh学习总结四(Mesh数据包分析)
  4. 【有料c++题目周刊 | 第六期】The Godfather
  5. 聚合码支付制作思路和流程
  6. 后金融风暴时代,什么样的开发人员能生存?
  7. 十条常见的互联网盈利模式
  8. 利用html-minifier和uglify-js对前端HTML/CSS/JS文件进行压缩
  9. c# 椭圆拟合库_利用C#版OpenCV实现圆心求取实例代码
  10. BUCK电路输出电容计算