BOM的含义

  BOM即Byte Order Mark字节序标记。BOM是为UTF-16和UTF-32准备的,用户标记字节序(byte order)。拿UTF-16来举例,其是以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流"594E",那么这是“奎”还是“乙”?

  Unicode规范中推荐的标记字节顺序的方法是BOM:在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"(零宽度无间断空间)的字符,它的编码是FEFF。而FEFF在UCS中是不不能再的字符(即不可见),所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者接收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称为BOM。

  UTF-8是以字节为编码单元,没有字节序的问题


延伸一下:

  UTF-8编码是以1个字节为单位进行处理的,不会受CPU大小端的影响;需要考虑下一位时就地址 + 1。

  UTF-16、UTF-32是以2个字节和4个字节为单位进行处理的,即1次读取2个字节或4个字节,这样一来,在存储和网络传输时就要考虑1个单位内2个字节或4个字节之间顺序的问题。


UTF-8 BOM

  UTF-8 BOM又叫UTF-8 签名,UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。当文本程序读取到以 EF BB BF开头的字节流时,就知道这是UTF-8编码了。Windows就是使用BOM来标记文本文件的编码方式的


补充:

"ZERO WIDTH NO-BREAK SPACE"字符的UCS编码为FEFF(假设为大端),对应的UTF-8编码为 EF BB BF


  即以EF BB BF开头的字节流可表明这是段UTF-8编码的字节流。但如果文件本身就是UTF-8编码的,EF BB BF这三个字节就毫无用处了。 所以,可以说BOM的存在对于UTF-8本身没有任何作用

UTF-8文件中包含BOM的坏处

  1、对php的影响

  php在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头的那三个EF BB BF字符,直接当做文本进行解析,导致解析错误。

  2、在linux上执行SQL脚本报错


  最近开发过程中遇到,windows下编写的SQL文件,在linux下执行时,总是报错。

  在文件的开头,无论是使用中文注释还是英文注释,甚至去掉注释,也会报SP2-0734: unknown command beginning "?<span "="">dec<span "="">lare ..." - rest of line ignored. 的错误。
<span "="">如下是文件开头部分

 --create tablespace
declare
v_tbs_name varchar2(200):='hytpdtsmsshistorydb';
begin

  报错如下:

 SP2-0734: unknown command beginning "?--create ..." - rest of line ignored.

 PL/SQL procedure successfully completed.

  网上没有找到类似问题的解决办法,且文件编码确认已经更改为utf-8,该问题困惑了我很久。
  最后查看一下BOM与 no BOM的区别,尝试更改为no BOM,居然就没有再出现错误。

  修改完成后,无论使用中文,还是英文,或者去掉注释,都能正常执行。


血泪建议:UTF-8最好不要带BOM

  UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。

  1、Linux中查看BOM的方法:使用less命令,其它命令可能看不到效果:

  发现词语之前多了一个<U+FEFF>。

  2、UTF-8去除BOM的方法

  Linux下:

  (1)

    1)vim打开文件

    2)执行:set nobomb

    3)保存:wq

  (2)

    dos2unix filename

    将windows格式文件转为Unix、Linux格式文件。该命令不仅可将windows文件的换行符\r\n转为Unix、Linux文件的换行符\n,还可以将UTF-8 Unicode (with BOM)转换为UTF-8 Unicode.

  PS:

  遇到一个比较坑爹的情况,1个UTF-8 Unicode (with BOM)文件中包含两个<U+FEFF>,这是无论使用方法(1)还是方法(2),都要执行两次才能将<U+FEFF>完全去除!!!

  (2)Windows下,使用NotePad++打开这个文件,然后选择“编码”,再选择“以UTF-8无BOM格式编码”,最后重新保存文件即可!

UTF-8和BOM的一些说明的更多相关文章

  1. utf 8无bom和utf 8什么区别

    今天在上传CSV文件的时候,Windows下调试一切正常.妈的一到Linux下面,就出现问题,第一行数据总是读取不出来, 利用print_r()打印出读取文件的内容,发现有一个很奇怪的字符在作怪.为什 ...

  2. 2dx中文乱码问题

    我们的代码里面有一个bug 为了跟之前兼容的策划导表工具兼容 导表工具导出的excel全部都是ansi的 为了兼容就只能手动改成utf 8 无bom格式 后来策划嫌烦了 就让在程序段处理这个 研究了好 ...

  3. 字符编码介绍及java中的应用

    字符编码,就是对日常的控制符号.文字和常用符号的二进制表示.为了准确的表示如何编号,怎么生产八位字节流,Unicode Technical Report (UTR) #17提出现代编码模型的5个层次: ...

  4. 字符集&各种编码&编码解码

    要理解乱码问题,首先需要理解几个概念:字符集.编码.编码规则.乱码 1. 字符集: 字符(Character)是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.字符集(Charact ...

  5. Java 字符编码(一)Unicode 字符编码

    Java 字符编码(一)Unicode 字符编码 Unicode(http://www.unicode.org/versions/#TUS_Latest_Version) 是一个编码方案,说白了希望给 ...

  6. PHP导出CSV文件出现乱码的解决方法

    在做项目时碰到使用外语的情况下,我们就会使用UTF-8编码.但是,在用PHP导出CSV文件时,如果写入的数据是使用UTF-8编码的日语.韩语之类的外文,就会出现乱码. 要解决PHP生成CSV文件的乱码 ...

  7. 【转】字符编码笔记:ASCII,Unicode 和 UTF-8

    原文:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html https://www.key-shortcut.com/ ...

  8. Ruby 对多语言的支持

    这是一篇翻译文章,原文链接 http://blog.grayproductions.net/articles/understanding_m17n.原文是一个系列,翻译过来整合成了一篇文章,对文章内容 ...

  9. Elasticsearch知识整理

    1:es介绍          Elasticsearch是一个基于Lucene的实时的分布式搜索和分析引擎.设计用于云计算中,          能够达到实时搜索,稳定,可靠,快速,安装使用方便.基 ...

  10. Python深入:编码问题总结

    转自:http://blog.csdn.net/gqtcgq/article/details/47068817 一:字符编码简介          1:ASCII          最初的计算机的使用 ...

随机推荐

  1. 你真的理解Java 注解吗?

    你真的理解Java 注解吗? 1.什么是注解? 官方解释: Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java ...

  2. 原生js放大镜效果

    效果: 1.  鼠标放上去会有半透明遮罩.右边会有大图片局部图 2.  鼠标移动时右边的大图片也会局部移动 放大镜的关键原理: 鼠标在小图片上移动时,通过捕捉鼠标在小图片上的位置,定位大图片的相应位置 ...

  3. 洛谷 UVA1328 Period

    洛谷 UVA1328 Period 洛谷传送门 题目描述 PDF 输入格式 无 输出格式 无 题意翻译 题意描述 对于给定字符串S的每个前缀,我们想知道它是否为周期串.也就还是说,它是否为某一字符串重 ...

  4. vue 父子父组件通过props传父页面请求后的数据

    父子父组件通过props传父页面请求后的数据,则在父页面的子组件上加上判断数据是否存在即可,如下 <gl-line-bar v-if="oneWeekBetEcharts" ...

  5. Redis缓存与数据库一致性解决方案

    背景 缓存是数据库的副本,应用在查询数据时,先从缓存中查询,如果命中直接返回,如果未命中,去数据库查询最新数据并返回,同时写入缓存. 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载.是应用架 ...

  6. Vue 从入门到进阶之路(十三)

    之前的文章我们介绍了一下 vue 中的作用域插槽,本章我们来看一下动态组件与 v-once 指令. <!DOCTYPE html> <html lang="en" ...

  7. react使用moment进行日期格式化

    导入moment import moment from 'moment'; 使用方式 年月日,时分秒 moment().format('YYYY-MM-DD HH:mm:ss'); // 2019-0 ...

  8. Java入门系列之集合ArrayList源码分析(七)

    前言 上一节我们通过排队类实现了类似ArrayList基本功能,当然还有很多欠缺考虑,只是为了我们学习集合而准备来着,本节我们来看看ArrayList源码中对于常用操作方法是如何进行的,请往下看. A ...

  9. 在nodejs中怎么使用redis缓存组件

    redis量个强大的缓存组件,可以部署在windows和linux环境之上,它有五大存储结构,其中有一种为列表list,它可以实现quene和stack的功能,即队列和堆栈的功能. 当然使用先安装py ...

  10. 资深程序员对于Python各个方向的面试经验分享,非常给力!

    之前早有前辈们说过,"裸辞一时爽,一直裸辞一直爽",这话一点不假,裸辞你要面临没有收入来源,但是每天眼睁睁看着各种花销不断支出的煎熬,我主要是觉得一边在上家公司工作一边去下家面试可 ...