前言
此前遇到过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. ...
随机推荐
-
sk_buff 里的len, data_len, skb_headlen
http://blog.csdn.net/kakadiablo/article/details/7948414 struct sk_buff *skb; skb->len 是data长度,包含所 ...
-
IAR FOR ARM的安装及破解
本博文主要是介绍如何安装以及破解IAR FOR ARM . 1.下载IAR FOR ARM以及注册机 IAR FOR ARM下载:http://pan.baidu.com/s/1i5t1qF7 注册机 ...
-
AttributeTargets 枚举
AttributeUsage AttributeTargets 在C#的类中,有的类加上了[AttributeUsage(AttributeTargets.Property)]这个是起什么作用的呢?A ...
-
2014.12.05(解决eclipse的adb打不开)
一.问题如下图所示 The connection to adb is down, and a severe error has occured.You must restart adb and Ecl ...
-
Washing Clothes_01背包
Description Dearboy was so busy recently that now he has piles of clothes to wash. Luckily, he has a ...
-
【LeetCode】66 &; 67- Plus One &; Add Binary
66 - Plus One Given a non-negative number represented as an array of digits, plus one to the number. ...
-
Javascript实现Web颜色值转换
最近一直忙碌于完成业务需求,好长时间没有写博客了.今天稍微有些时间,翻看了一下最近项目中的一些前端代码,看到Web颜色转换功能的时候,突然想到当我们在做一些颜色设置/编辑的需求时,经常会涉及到各种颜色 ...
-
JavaScript-学习一字符串
字符串可以存储一系列字符,如 "John Doe". 字符串可以是插入到引号中的任何字符.你可以使用单引号或双引号: 用于字符串的 + 运算符 + 运算符用于把文本值或字符串变量加 ...
-
convert用法(数据库中原本储存的格式是Nvarchar,如何修改成datetime格式)
查询这张表得到的数据如图 select CONVERT(nvarchar,substring([purchase-date],1,4)) +'-'+CONVERT(nvarchar,substring ...
-
Akka 简介与入门
Akka 简介与入门 http://www.thinksaas.cn/group/topic/344095/ 参考官网 http://akka.io/ 开源代码 https://github.co ...