最近在给项目团队开发一个基于 Java 的通用的 XML 分析器时,设计了一个方法,能够读取现成的 XML 文件进行分析处理,当然 XML 都是采用 UTF-8 进行编码的。但是在用 UltraEdit 写了一个测试用的 UTF-8 XML 文件后,程序在读取该文件时发生错误:

Parse Fatal Error at line 1 column 1: 前言中不允许有内容。org.xml.sax.SAXParseException: Content is not allowed in prolog....

反复检查代码不可能出问题,XML 文件也是正确的,试来试去百思不得其解。于是用 IDEA 编辑器写了一个同样的 XML 文件,程序运行正常。在网上找来找去,无意中发现 UTF-8 编码居然有一个所谓的 BOM 文件头问题。那么,BOM 又是什么玩意呢?

BOM 即 Byte Order Mark,就是字节序标记。在 UCS 编码中有一个叫做“ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是 FEFF。而 FFFE 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。UCS 规范建议我们在传输字节流前,先传输字符“ZERO WIDTH NO-BREAK SPACE”,这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;如果收到 FFFE,就表明这个字节流是 Little-Endian 的。因此字符“ZERO WIDTH NO-BREAK SPACE”又被称作 BOM。

UTF-8 本身不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符“ZERO WIDTH NO-BREAK SPACE”的 UTF-8 编码是 EF BB BF。所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8 编码了。所以,有些编辑器会在创建并保存 UTF-8 编码的 XML 文件时自动在文件头部增加 EF BB BF 这三个字节,用来做 BOM。UltraEdit 默认就是这样,自作聪明反倒惹麻烦!IDEA 编辑器创建生成的 UTF-8 编码的 XML 文件就没有这个 BOM 文件头,所以才出现了本文开头所描述的问题现象。

后来研究了一下 UltraEdit,发现它倒是提供了一个保存选项,在第一次保存或者以后“另存为”时,选择保存为 UTF-8 without BOM 就可以了。

既然找到原因了,我想不能让各种编辑器来迁就我的程序,还是让我的程序去迁就它们吧,也就是在程序中增加自动识别 BOM 文件头的功能。这样一来,无论是否带有 BOM 文件头的 UTF-8 编码的 XML 文件,我的程序都能够兼容使用,事实上后来实现这个功能才发现,很简单,没有增加太多工作量,何乐而不为呢?

UTF-8 编码的文件在处理时要注意 BOM 文件头问题的更多相关文章

  1. pycharm新建py文件时,自动补充文件头注释信息

    步骤: 1.File -->Settings 2.选择 File and Code Templates -> Files -> Python Script 文件头注释信息代码样式: ...

  2. Pycharm在创建py文件时,如何自动添加文件头注释(类似于钩子特性)?

    在每次新建一个py文件的时候 1 如何自动添加/usr/bin/env python2 自动添加 coding=utf8 操作方法: File->settings->Editor-> ...

  3. pycharm 创建文件时,自动添加文件头注释

    File->settings->Editor->File and Code Templates->Python Script # -*- coding: utf-8 -*- & ...

  4. pycharm在创建py文件时,自动添加文件头注释

    File -> settings -> Editor-> File and Code Templates -> Python Script 添加内容: #!/usr/bin/e ...

  5. day07--字符编码、文件处理

    今日内容: 字符编码 文件处理 字符编码: 把字符编码成二进制 各个国家拥有各自的字符编码,这样会导致交流产生问题.所以后面推出了内存使用unicode,硬盘使用UTF-8这个模式 unicode有两 ...

  6. 【CTF杂项】常见文件文件头文件尾格式总结及各类文件头

    文件头文件尾总结 JPEG (jpg), 文件头:FFD8FF 文件尾:FF D9PNG (png), 文件头:89504E47 文件尾:AE 42 60 82GIF (gif), 文件头:47494 ...

  7. day 10 字符编码和文件处理 细节整理

    pycharm是文本编辑器. 大概理解为:  输出到屏幕上的时候,是解码过的字符串,用 decode 处理的时候要编码成相应的流, encode 成你要用的格式就可以了 1 .字符编码: 字符==== ...

  8. Python全栈开发之路 【第三篇】:Python基础之字符编码和文件操作

    本节内容 一.三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件语句: if 条件成立: val = 1 else: val = 2 改成三元运算: val = 1 if 条件成 ...

  9. Python自动化开发 - 字符编码、文件和集合

    本节内容 字符编码 文件操作 集合 一.字符编码 1.编码 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.解决思路:数字与符号建立一对一映射,用不同数字表示不同符号. ASCI ...

随机推荐

  1. 2019的hdu暑假作业(欢迎纠错)

    1219 遍历计数. #include<bits/stdc++.h> #define QAQ 0 using namespace std; ]; ]; int main(){ )){ me ...

  2. 菜鸟教你如何通俗理解——>集群、负载均衡、分布式

    在“高并发,海量数据,分布式,NoSql,云计算......”概念满天飞的年代,相信不少朋友都听说过甚至常与人提起“集群,负载均衡”等,但不是所有人都有机会真正接触到这些技术,也不是所有人都真正理解了 ...

  3. POI写入word doc 03 模板的实例

    在使用POI写word doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过HWPFDocument来写的,而HWPFDocument是要依附于一个doc文件的.所以通 ...

  4. ios之UITextView

    我们计划创建UITextView,实现UITextViewDelegate协议方法,使用NSLog检查该方法何时被调用.我们还会接触到如何在TextView中限制字符的数量,以及如何使用return键 ...

  5. sqlite查看所有表名、判断表是否存在,字段名及字段信息

    sqlite查看所有表名.判断表是否存在,字段名及字段信息   sqlite查看所有表名及字段名查询table,type 段是'table',name段是table的名字, select name f ...

  6. php登录加密加盐

    1         背景 涉及身份验证的系统都需要存储用户的认证信息,常用的用户认证方式主要为用户名和密码的方式,为了安全起见,用户输入的密码需要保存为密文形式,可采用已公开的不可逆的hash加密算法 ...

  7. 时间格式的处理和数据填充和分页---laravel

    时间格式文档地址:http://carbon.nesbot.com/docs/ 这是些时间格式,只需要我们这么做就可以 我们在模板层,找到对应的模型对象那里进行处理就可以啦 2018-11-08 16 ...

  8. 【php】 php能做什么

    来源:php官方文档 网站和 web 应用程序(服务器端脚本) 命令行脚本 桌面(GUI)应用程序 相信大多数人都不知道第三种,用php竟然可以写GUI,当然是基于PHP-GTK扩展写的

  9. BIOM Table-codes

    import numpy from biom.table import Table ========================================================== ...

  10. (转)UITextField

    //初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...