【Python】使用codecs模块进行文件操作及消除文件中的BOM
前言
此前遇到过UTF8格式的文件有无BOM的导致的问题,最近在做自动化测试,读写配置文件时又遇到类似的问题,和此前一样,又是折腾了挺久之后,通过工具比较才知道原因。

两次在一个问题上面栽更头,就在想有没有一个一劳永逸的方法避免这个问题,或者能做到检测,不用到最后借助Beyond Compare进行16进制比较。
之前的博客中UTF8格式的文件有无BOM做了比较详细的说明,有兴趣的可以看看:
UTF-8文件的Unicode签名BOM(Byte Order Mark)问题记录(EF BB BF)
Python codecs
此前很少使用codecs,查阅了相关资料知道这个是一个好东西。
比如说当我们有数据要保存的时候,大多数时候会选择保存到TXT中,当然数据量大的时候,保存到数据库还是比较方便,然后在网络传输的时候需要序列号、json化。
而我们操作txt平常用得最多的就是open内置函数,或者file这个工厂函数,两者效果基本一样。
但是我们用open方法打开文件有时候会有一些问题,因为open打开文件只能写入str类型,而不会管字符串是什么编码方式。
例如这样是可以的,示例:
>>> fr = open('test.txt','a')
>>> line1 = "我爱祖国"
>>> fr.write(line1)
但是有时候我们爬虫或者其他方式得到一些数据写入文件时会有编码不统一的问题,此时写入open方式打开的文件就有问题了。示例:
>>> line2 = u'我爱祖国'
>>> fr.write(line2)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
fr.write(line2)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-11: ordinal not in range(128)
怎么办?我们可以将上面的line2编码成str类型。
操作步骤:先把原数据decode为unicode再encode为str,太麻烦了。。。
input文件(gbk, utf-8...) ----decode-----> unicode -------encode------> output文件(gbk, utf-8...)
其实Python提供了更简单的做法,那就是今天的主角codecs.open,示例:
>>> import codecs
>>> fw = codecs.open('test1.txt','a','utf-8')
>>> fw.write(line2)
>>>
没有报错,写入成功!
其实Python对多国语言的处理是支持的很好的,它可以处理当下任意编码的字符。
有一点需要清楚的是,当python要做编码转换的时候,会借助于内部的编码,转换过程是这样的:
原有编码 -> 内部编码 -> 目的编码
而codecs提供的方法可以指定一个编码打开文件,使用这个方法打开的文件读取返回的将是unicode。写入时,如果参数是unicode,则使用open()时指定的编码进行编码后写入;如果是str,则先根据源代码文件声明的字符编码,解码成unicode后再进行前述 操作。相对内置的open()来说,这个方法不容易在编码上出现问题。所以,推荐大家在文件读写的时候使用codecs
检测及消除BOM
然后继续我们今天的另外一个主题,怎么样消除UTF-8文件中的名BOM(Byte Order Mark),十六进制编码(EF BB BF),博主的方法有些取巧但是也比较高效,主要用到了codecs的函数BOM_UTF8,如果发现BOM_UTF8,则直接改写文件内容。
示例代码:
import codecs
with open(config_path) as source_file:
data = source_file.read()
# remove BOM
if data[:3] == codecs.BOM_UTF8: # 判断是否为带BOM文件
data = data[3:]
with codecs.open(config_path) as dest_file:
dest_file.write(data)
相关读写模式
codecs有如下的读写模式,和open用法基本一致。
| 模式 | 描述 |
|---|---|
| r | 仅读,待打开的文件必须存在 |
| w | 仅写,若文件已存在,内容将先被清空 |
| a | 仅写,若文件已存在,内容不会清空 |
| r+ | 读写,待打开的文件必须存在 |
| w+ | 读写,若文件已存在,内容将先被清空 |
| a+ | 读写,若文件已存在,内容不会清空 |
| rb | 仅读,二进制,待打开的文件必须存在 |
| wb | 仅写,二进制,若文件已存在,内容将先被清空 |
| ab | 仅写,二进制,若文件已存在,内容不会清空 |
| r+b | 读写,二进制,待打开的文件必须存在 |
| w+b | 读写,二进制,若文件已存在,内容将先被清空 |
| a+b | 读写,二进制,若文件已存在,内容不会清空 |
相关资料:
https://www.cnblogs.com/buptldf/p/4805879.html
https://blog.csdn.net/chenyxh2005/article/details/72465758
https://blog.csdn.net/zhaoweikid/article/details/1642015
【Python】使用codecs模块进行文件操作及消除文件中的BOM的更多相关文章
- 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容
孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...
- JAVASE02-Unit06: 文件操作——File 、 文件操作—— RandomAccessFile
Unit06: 文件操作--File . 文件操作-- RandomAccessFile java.io.FileFile的每一个实例是用来表示文件系统中的一个文件或目录 package day06; ...
- Unix无缓冲文件操作函数、文件信息查询
问题描述: Unix无缓冲文件操作函数.文件信息查询 问题解决: struct stat 结构体信息: 具体代码: 具体源文件:
- 重新想象 Windows 8 Store Apps (24) - 文件系统: Application Data 中的文件操作, Package 中的文件操作, 可移动存储中的文件操作
原文:重新想象 Windows 8 Store Apps (24) - 文件系统: Application Data 中的文件操作, Package 中的文件操作, 可移动存储中的文件操作 [源码下载 ...
- JAVA文件操作类和文件夹的操作代码示例
JAVA文件操作类和文件夹的操作代码实例,包括读取文本文件内容, 新建目录,多级目录创建,新建文件,有编码方式的文件创建, 删除文件,删除文件夹,删除指定文件夹下所有文件, 复制单个文件,复制整个文件 ...
- java文件操作(普通文件以及配置文件的读写操作)
转自:java文件操作(普通文件以及配置文件的读写操作) 读取普通文件 : /** * xiangqiao123欢迎你 如果对代码有疑问可以加qq群咨询:151648295 * * 读取MyFile文 ...
- Python:文件操作总结1——文件基本操作
一.文件的操作流程 1.打开文件,得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 二.文件的打开与关闭 A.文件的打开——open函数 语法:open(file[,mode[, ...
- 文件操作 - 三元运算/chardet/文件操作r w/文件的操作方法
Alex:读书可以改变一个人的气质读书:豆瓣: 1年读20本 你的问题:想法太多,读书太少 书:追风筝的人,白鹿原 电影:阿甘正传 辛德勒名单---------------------------- ...
- day8 八、文件操作模式、文件的复制与文件游标操作
一.文件操作 1.wr模式结合 ① w = open('1.txt', 'w', encoding='utf-8') # w:没有文件新建文件,有文件就清空文件 w.write('000\n') w. ...
随机推荐
- 封装自己的getClassName函数
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux(Centos)下搭建SVN服务器
鉴于在搭建时,参考网上很多资料,网上资料在有用的同时,也坑了很多人,本文的目的,也就是想让后继之人在搭建svn服务器时不再犯错,不再被网上漫天的坑爹作品所坑害,故此总结! /******开始***** ...
- Tomcat 400错误 问题集锦
1.前后台参数类型不一致 上图错误提示就是客户端发送的请求不能找到你的具体的页面或者地址,这是Spring MVC抛出的错误,这样我们就要进行参数的检查,一定是JSP提交的参数和Controller里 ...
- elk----es settings--logstash--performance---bigdesk---logstash plugin online/offline
www.cnblogs.com/tangr206/articles/2274845.html yum timeout error(/etc/resolv.conf) elk: elasticsearc ...
- 关于Python装饰器内层函数为什么要return目标函数的一些个人见解
https://blog.csdn.net/try_test_python/article/details/80802199 前几天在学装饰器的时候,关于装饰器内层函数调用目标函数时是否return目 ...
- nodejs Async详解之二:工具类
Async中提供了几个工具类,给我们提供一些小便利: memoize unmemoize log dir noConflict 1. memoize(fn, [hasher]) 有一些方法比较耗时,且 ...
- Yarn框架和工作流程研究
一.概述 将公司集群升级到Yarn已经有一段时间,自己也对Yarn也研究了一段时间,现在开始记录一下自己在研究Yarn过程中的一些笔记.这篇blog主要主要从大体上说说Yarn的基本架构以及其 ...
- 基于 Spark 的文本情感分析
转载自:https://www.ibm.com/developerworks/cn/cognitive/library/cc-1606-spark-seniment-analysis/index.ht ...
- 关于ML的思考讲座-周zh-11.30日
1.深度神经网络 1.以往神经网络采用单或双隐层结构,虽然参照了生物上的神经元,但是从本质上来说还是数学,以函数嵌套形成. 2.通常使用的激活函数是连续可微(differentiable)的,sigm ...
- 中文乱码—Servlet—SpringMVC
一.SpringMVC中的中文乱码问题 a:处理全局请求的中文乱码(配置Web.xml的字符编码过滤器) <filter> <filter-name>encodingFilte ...