欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

CSV读取与写入的常见问题(空行、BOM、r/w/a模式、指针)

程序员文章站 2022-06-15 19:12:53
1. 多余的空行原因python正常写入文件的时候,每行的结束默认添加’\n’,即0x0D,而writerow命令的结束会再增加一个0x0D0A,因此对于windows系统来说,就是两行。采用’ b’参数,用二进制进行文件写入,系统默认是不添加0x0D的(故python2.x中的解决方式是使用“wb模式打开文件”,该方法python3.x中已不适用,会报错如下)。TypeError: a bytes-like object is required, not 'str'解决方法打开文件时添加new...
import csv

1. 多余的空行

原因

python正常写入文件的时候,每行的结束默认添加’\n’,即0x0D,而writerow命令的结束会再增加一个0x0D0A,因此对于windows系统来说,就是两行。采用’ b’参数,用二进制进行文件写入,系统默认是不添加0x0D的(故python2.x中的解决方式是使用“wb模式打开文件”,该方法python3.x中已不适用,会报错如下)。

TypeError: a bytes-like object is required, not 'str'

解决方法

打开文件时添加newline=“”。例如。

with open(filename,"w",encoding="utf-8",newline="") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerows(csv_list)

writerow()和writerows()区别

2. BOM对读写的影响

什么是BOM

BOM(byte-order mark,字节顺序标记):
Unix系统中都是使用的utf-8编码,不存在BOM问题。比如在Mac用open打开utf-8编码的csv文件并不用加encoding=“utf-8”。

with open(filename) as csvfile:
        writer = csv.writer(csvfile)
        writer.writerows(csv_list)

Windows系统的中文环境很多软件默认字符编码为gbk,比如如果用上面的语句打开csv文件则会报错。

'gbk' codec can't decode byte

而utf-8保存的文件要在windows下用Excel正常打开的话(不乱码),必须在文件最前面加入BOM。

注意

Mac下有种情况csv文件会带BOM头:
文件原本是xlsx格式,在Excel中用”save as“转换得到的csv文件,会带BOM头。

读取带有BOM头的csv文件

问题:首行出现“\ufeff”

如果不处理,读取的列表中,第一项最前面会多“\ufeff”几个字母。如果这一项再作为内容被写入csv,则首行最前面会好像出现了乱码。

解决方法

打开文件时的encoding = “utf-8” 改为encoding = “utf-8-sig”。

with open(filename,"w",encoding="utf-8-sig",newline="") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerows(csv_list)

关于”utf-8“ 与“uft-8-sig":
”utf-8“ 是以字节为编码单元,它的字节顺序在所有系统中都是一样的,没有字节序问题,因此它不需要BOM,所以当用”utf-8”编码方式读取带有BOM的文件时,它会把BOM当做是文件内容来处理, 也就会发生类似上边的错误.
“uft-8-sig"中sig即 signature ,也就是”带有签名的utf-8”,因此”utf-8-sig”读取带有BOM的”utf-8文件时”会把BOM单独处理,与文本内容隔离开。

写入带有BOM头的csv文件

不带BOM头的csv文件在Windows下用Excel打开会乱码,Notepad++打开不会乱码。
用Excel打开:
CSV读取与写入的常见问题(空行、BOM、r/w/a模式、指针)
用Notepad++打开:
CSV读取与写入的常见问题(空行、BOM、r/w/a模式、指针)
写入csv文件时写入BOM头的方法:在写入文件内容之前写入“\xef\xbb\xbf”。

with open(filename,"w",encoding="utf-8",newline="") as csvfile:
        writer = csv.writer(csvfile)
		writer.write([“\xef\xbb\xbf”]) 
		#或writer.writerow([“\xef\xbb\xbf”])
		writer.writerows(csv_list)

3. 其他

读取写入模式

r:只读,文件不存在则报错
r+:可读可写,文件不存在则报错,覆盖
w:只写,文件不存在则创建,覆盖
w+:可读可写,文件不存在则创建,覆盖
rb,wb:类似w,r,用于二进制文件读写
a:只写,文件不存在则创建,追加
a+:可读可写,文件不存在则创建,追加

指针

  1. 每次打开文件默认指针是在开头的。可以通过file.tell()查询当前指针位置,file.seek()来设置指针的位置进行读写操作。
  2. 在打开的文件中(一个with open内部),每次操作都是从当前指针指向位置向后进行读写,读写完成指针停留在当前文档的最后。

最后

这些都是最近做数据处理过程中遇到的问题,如果有不对的地方欢迎大家批评指正,共同学习。

本文地址:https://blog.csdn.net/Parzival_/article/details/107240185