BOM-字节序标记
BOM——Byte Order Mark 字节序标记
首先是什么是字节序? 字节序:与二进制数据在机器存放位置相关的! 可分为两类:
1. 小端字节序: 低地址放低位数据。 x86系列的计算机就使用这种字节序
2. 大端字节序: 低地址放高位数据。 ibm系使用
举个例子.. 写个简单程序来看看自己电脑使用神马字节序存放数据的!
#include <stdio.h> int main(int argc, char const *argv[]) { FILE *fp = NULL; int data = 109034; // 1A9EA if((fp = fopen("m.data", "wb+")) != NULL) { fwrite(&data, sizeof(int), 1, fp); } fclose(fp); return 0; }
使用16进制编辑器(Nodepad++安装个HexEditor即可) 查看程序生成的m.data文件!
结果如下: 从左到右地址递增
ea a9 01 00
可以看出: data变量的ea字节存放在m.data低位字节, 因此本人的机器是使用小字节序存放数据的。
回到正题, UTF-8编码本身是不需要使用BOM来表明字节顺序,但可以用BOM来表明编码方式。也就是告诉编辑器知道它是个utf-8之外什么用处都没有。带BOM文件特征:以 EF BB BF开头
BOM本是为 UTF-16 和 UTF-32 准备的,用于标记字节序。 对于多系统(多语言)使用者来说, 带BOM的UTF-8简直就是一场灾难。可以参考:UTF8最好不要带BOM,附许多经典评论
%>_<%: 感觉立了个 flag,今天(2016-09-28)碰到一个破系统... 上传的文件必须得是 UTF-8-BOM 格式的
String bomStr = new String(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF}, Charset.forName('UTF-8')); // 加上这破玩意就行了
另外: 检测文件编码这个功能看着容易,实际很难! 就举个最最简单的例子: 创建一个信息量很小的gbk编码的文件,内容就一字: “键” 。
1. 使用nodepad++打开虽然没乱码,但是右下角为ANSI编码
2. 使用sublime text 3(带ConvertToUTF8插件)打开, 结果是乱码! 需要自己选择合适的编码方式打开
3. 使用python的chardet库来查看文件的编码, 结果输出: {'confidence': 0.73, 'encoding': 'windows-1252'}
So, 在项目中一定要统一文件的编码! 这至关重要