utf-8和utf-8-sig的区别
前言:在写入csv文件中,出现了乱码的问题。
解决:utf-8 改为utf-8-sig
区别如下:
1、”utf-8“ 是以字节为编码单元,它的字节顺序在所有系统中都是一样的,没有字节序问题,因此它不需要BOM,所以当用"utf-8"编码方式读取带有BOM的文件时,它会把BOM当做是文件内容来处理, 也就会发生类似上边的错误.
2、“uft-8-sig"中sig全拼为 signature 也就是"带有签名的utf-8”, 因此"utf-8-sig"读取带有BOM的"utf-8文件时"会把BOM单独处理,与文本内容隔离开,也是我们期望的结果.
with open('data.csv', 'w',encoding='utf_8_sig') as fp:
utf-8保存的csv格式文件要让Excel正常打开的话,需要在文件最前面加入BOM(Byte order mark)。如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
所以在write文件的内容数据之前,先write一下BOM。如下面代码
FileOutputStream fos = new FileOutputStream(new File(this.csvFileAbsolutePath));
byte [] bs = { (byte)0xEF, (byte)0xBB, (byte)0xBF}; //UTF-8编码
fos.write(bs);
fos.write(...);
fos.close();
这样添加了BOM的CSV文件用excel直接打开,是不会出现乱码的。
我当时遇到的问题是这样的。下载CSV文件,用excel打开,中文乱码,用atom,notepad++和 记事本打开,显示正常。 查资料发现是excel不能识别无BOM头的unicode文件问题,就是excel在打开CSV文件时默认用ASNI打开。 所以需要添加BOM头。
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 "="">如下是文件开头部分
1 --create tablespace
2 declare
3 v_tbs_name varchar2(200):='hytpdtsmsshistorydb';
4 begin
报错如下:
1 SP2-0734: unknown command beginning "?--create ..." - rest of line ignored.
2
3
4 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格式编码”,最后重新保存文件即可!
参考资料来源:https://www.cnblogs.com/Allen-rg/p/10536081.html
utf-8和utf-8-sig的区别的更多相关文章
- UTF—8与UTF—8(无bom)格式
BOM——Byte Order Mark,就是字节序标记 在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF.而FFFE在U ...
- Unicode、UTF-8 和 ISO8859-1到底有什么区别
说明:本文转载于新浪博客,旨在方便知识总结.原文地址:http://blog.sina.com.cn/s/blog_673c81990100t1lc.html 本文主要包括以下几个方面:编码基本知识, ...
- Unicode、UTF-8 和 ISO8859-1
Unicode.UTF-8 和 ISO8859-1到底有什么区别 1.本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文" ...
- UniEAP UTF 用户手册 (引擎)
目录 第1章 概述 5 1.1 术语解释 5 第2章 测试文件组织 6 2.1 测试执行文件详解 7 2.1.1 参数配置 7 2.1.2 测试报告配置 9 2.1.3 浏览器类型配置 9 2.1.4 ...
- GBK、GB2312、iso-8859-1之间的区别
转自:http://blog.csdn.net/jerry_bj/article/details/5714745 GBK.GB2312.iso-8859-1之间的区别 GB2312,由中华人民共和国政 ...
- AJPFX解析关于编码ansi、GB2312、unicode与utf-8的区别
大家平时遇到乱码问题是否有自己的一套解决方案?这篇文章就是介绍一下常用的编码方式关于编码ansi.GB2312.unicode与utf-8的区别 先做一个小小的试验: 在一个文件夹里,把一个txt文本 ...
- ASCII码、ISO8859-1、Unicode、GBK和UTF-8 的区别
为什么需要编码? 计算机中最小的存储单位是字节(byte),一个字节所能表示的字符数又有限,1byte=8bit,一个字节最多也只能表示255个字符,而世界上的语种又多,都有各种不同的字符,无法用一个 ...
- 关于UltraEdit的两个小问题
问题一:如何让Java在编写过程中的关键字着色? 首先,需要把编辑的文件名字后缀更改为.java; 然后,找到UltraEdit的安装目录下的wordfile文件夹(以前是一个wordfile.txt ...
- java:[1,1] 需要class, interface或enum
状态: cmd编译.java文件时报异常:java:[1,1] 需要class, interface或enum异常原因: 主要原因是java文件的编码问题. 在中文操作系统中,使用一贯的"j ...
- javac 命令
HelloWorld.java:1: 需要为 class.interface 或 enum 锘缝ublic class HelloWorld{ ^ 1 错误 这个错误出现的原因主要是在中文操作系统中, ...
随机推荐
- 如何使用dockerfile将jar包生成镜像
1.编写dockersfile FROM java:8 ADD SPRINGCLOUD.jar app.jar RUN bash -c ‘touch /app.jar’ ENTRYPOINT [&qu ...
- [LeetCode]66. 加一(数组)
###题目 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 ...
- 最优得分 score
Solution: 一道很典型的dp题目, 对于 20% 的数据(Bi=0),直接使用01背包即可. 对于 100% 的数据,我们需要进行分析,当我们对 …a,b… 和 …b,a… (…表示的是相同的 ...
- json出现引用 "$ref": "$.conpolice[2]"
1. 出现这个问题一般是因为代码循环引用出现的问题,可以改变逻辑,也可以直接加上下面加粗的代码 JSONObject jsonObject = new JSONObject(); jsonObject ...
- 记一次由selinux引起的使用cat查看文件报错Permission denied的问题排查
事件起因:如下 1.在服务器上root用户,定期会生成一个文件,到/tmp目录,如:qq_5201351.txt,给other加上了r读取 2.zabbix端会周期性取这台服务器/tmp/qq_520 ...
- Java高级开发必会的50个性能优化的细节(珍藏版)
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. ● 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短 ...
- GEKCTF2020-web
GEKCTF [GKCTF2020]CheckIN97 <title>Check_In</title> <?php highlight_file(__FILE__); c ...
- mac电脑,charles,安卓手机如何配置代理,以及配置代理之后无法上网。已解决
设备: 电脑:mac book pro 手机:小米10 charles:4.5.6 方法一: 步骤: 首先确保电脑,手机在同一局域网, 1. charles设置代理:proxy -> proxy ...
- Python-属性描叙符协议ORM实现原理依据- __set__ __get__ __delete__
class CheckString: def __init__(self, variable_type): self.variable_type = variable_type def __set__ ...
- 基础篇:深入解析JAVA注解机制
目录 java实现注解的底层原理和概念 五种元注解详解 使用动态代理机制处理注解 spring.AOP和注解机制 (题外)@FunctionalInterface原理介绍 欢迎指正文中错误 关注公众号 ...