文本文件和二进制文件
按文件中数据组织形式,我们把文件分为文本文件和二进制文件两大类。
文本文件
文本文件存储的是普通的字符文本,python默认为unicode字符集。
二进制文件
二进制文件把数据内容用字节进行存储。必须使用专有的软件解码。常见的有:MP4、JPG、doc、xls等。
文件操作相关模块
名称 | 说明 |
io模块 | 文件流的输入和输出操作 |
os模块 | 基本操作系统功能,包括文件操作 |
glob模块 | 查找符合特定规则的文件路径名 |
fnmatch模块 | 使用模式来匹配文件路径名 |
fileinput模块 | 处理多个输入文件 |
filecmp模块 | 用于文件的比较 |
csv模块 | 用于处理csv文件 |
pickle和cPickle | 用于序列化和反序列化 |
xml包 | 用于XML数据处理 |
bz2、gzip、zipfile、zlib、tarfile | 用于处理压缩和解压缩文件 |
创建文件对象open()
open()函数用于创建文件对象,基本语法格式如下:
open(文件名,打开方式)
模式 | 描述 |
r | 读,read模式 |
w | 写,write模式。如果文件不存在则创建;如果文件存在,则重写新内容 |
a | 追加,append模式。如果文件不存在则创建;如果文件存在,则在文件末尾追加新内容。 |
b | 二进制,binary模式,可与其他模式组合使用 |
+ | 读、写模式。可与其他模式组合使用 |
文本文件对象和二进制文件对象的创建:
- 如果没有增加模式b,则默认创建的是文本文件对象,处理的基本单元是字符
- 如果是二进制模式b,则创建的是二进制文件对象,处理的基本单元是字节。
文本文件的写入操作:
文本文件的写入一般就是三个步骤:
- 创建文件对象
- 写入数据
- 关闭文件对象
f = open(r"e:/01_PythonTest/a.txt",'a')
s = "Python\nJava\tC++"
f.write(s)
f.close()
## 使用with上下文管理
with open(r"e:/01_PythonTest/a.txt",'a') as f:
s = "with上下文管理"
f.write(s)
常用编码介绍
ASCII
American Standard Code for Information Interchange,美国信息交换标准代码。这是世界上最早最通用的单字节编码系统,主要用来显示现代英语及其他西欧语言。
ASCII码用7位表示,只能表示128个字符。只定义了128个字符,用7bit即可完全编码。儿一字节8bit的容量是256,所以一字节ASCII的编码最高位总是0
ISO8859-1
ISO8859-1又称Latin-1,是一个8位单字节字符集,它把ASCII的最高位也利用起来,并兼容了ASCII,新增的空间是128,但它并没有完全用完。
GB2312,GBK,GB18030
GB2312全称位信息交换用汉字编码字符集,是中国于1980年发布,主要用于计算机系统中的汉字处理。GB2312覆盖了大部分的汉字,但是不能处理像古汉语等特殊的罕用字。GB2312完全兼容ISO8859-1
GBK全称Chinese Internal Code Specification,即汉字内码扩展规范,于1995年指定。它主要是扩展了GB2312,在它的基础上又加了更多汉字。
GB18030。现在最新的内码字集于2000年发布,并于2001年强制执行。包含了中国大部分少数名族的语言字符。主要采用单字节、双字节、四字节对字符编码,它是向下兼容GB2312和GBK的。虽然是强制使用的标准,但是实际生产中使用很少,用的最多的反而是GBK和GB2312
Unicode
Unicode编码设计成了固定两个字节,所有的字符都用16位表示,包括之前只占8位的英文字符等,所以会造成空间的浪费,Unicode在很长一段时间内都没有得到推广应用。Unicode完全重新设计,不兼容ISO8859-1,也不兼容其他编码。
UTF-8
对于英文字母,Unicode也需要两个字节来表示,所以Unicode不便于传输和存储,因此产生了UTF编码,全称8-bit Unicode Transformation Format。UTF-8兼容ISO-8859-1编码,同时也可以用来表示所有语言的字符,不过UTF编码是不定长编码,每一个字符的长度从1-4个字节不等,其中,英文字母都是用一个字节表示,儿汉字使用三个字节。
中文乱码问题
windows操作系统默认的编码是GBK,Linux操作系统默认的编码是UTF-8.当我们使用open()时,调用的是操作系统打开的文件,默认的编码时GBK。指定文件编码
f = open(r"a.txt","w",encoding="utf-8")
write()、writelines()写入数据
write(a):把字符a写入文件中
writelines(b):把字符串列表写入文件中,不添加换行符
f = open(r"a.txt","w",encoding="utf-8")
s = ["竹","筒","饭"]
f.writelines(s)
f.close()
# 文本中显示"竹筒饭"
close()关闭文件流
由于文件底层是由操作系统控制的,所以我们打开的文件对象必须显式调用close()方法关闭文件对象。当调用close()方法时,首先会把缓冲区数据写入文件(也可以直接调用flush()方法),再关闭文件,释放文件对象。
为了确保打开的文件正常关闭,一般结合异常机制的finally或with关键字实现无论何种情况都能关闭打开的文件对象。
try:
f = open(r"b.txt","a")
s = "abc"
f.write(s)
except BaseException as e:
print(e)
finally:
f.close()
with语句
with关键字可以自动管理上下文资源。不论说明原因跳出with块,都能确保文件正常关闭。并且可以再代码执行完毕后自动还原进入该代码时的现场。
s = ["a","b","c"]
with open(r"c.txt","w") as f:
f.writelines(s)
文本文件的读取
文本文件的读取一般使用如下三种方法:
- read([size])从文件中读取size个字符,并作为结果返回。如果没有size参数,则读取整个文件。读取到文本末尾,会返回空字符串
- readline(),读取一行内容作为结果返回。读取到文本末尾会返回空字符串
- readlines(),文本文件中,每一行作为一个字符串存入列表中,返回该列表
# 读取一个文件前4个字符
with open(r"a.txt",'r',encoding="utf-8") as f:
# a.txt中的内容是"竹筒饭123456789"
print("第一次读的内容:{}".format(f.read(4)))
print("第一次读的内容:{}".format(f.read()))
"""
第一次读的内容:竹筒饭1
第一次读的内容:23456789
"""
with open(r"b.txt","r",encoding="utf-8") as f:
# b.txt中的内容是"abc\ndef\nghi"
print(f.readline()) # abc
with open(r"b.txt","r",encoding="utf-8") as f:
print(f.readlines()) # ['abc\n', 'def\n', 'ghi']
在每行末尾添加行号
# 在每行末尾添加行号
with open(r"b.txt","r") as f:
lines = f.readlines()
lines_2 = [line.rstrip()+" #"+str(index)+"\n" for index,line in zip(range(1,len(lines)+1),lines)]
print(lines_2)
with open(r"b.txt","w") as f:
f.writelines(lines_2)
"""
b.txt由"abc\ndef\nghi"
变成"abc #1\ndef #2\nghi #3"
"""
二进制文件的读写
二进制文件的处理流程和文本文件流程一致。首先还是创建文件对象,不过,需要指定二进制模式,从而创建二进制文件对象。
with open('img.png','rb') as srcFile, open('img_copy.png','wb') as destFile:
for line in srcFile:
destFile.write(line)
文件对象的常用属性和方法
属性 | 说明 |
---|---|
name | 返回文件的名字 |
mode | 返回文件的打开模式 |
closed | 若文件被关闭, 则返回True |
文件对象的打开模式
模式 | 说明 |
---|---|
r | 读模式 |
w | 写模式 |
a | 追加模式 |
b | 二进制模式(可与其他模式组合) |
+ | 读写模式(可以其他模式组合) |
文件对象的常用方法
方法名 | 说明 |
---|---|
read([size]) | 从文件中读取size个字节或字符的内容返回。若省略[size],则读取到文件末尾,即一次读取文件所有内容 |
readline() | 从文本文件中读取一行内容 |
readlines() | 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回 |
write(str) | 将字符串str内容写入文件 |
writelines(s) | 将字符串列表s写入文件文件,不添加换行符 |
seek(offset [,whence]) | 把文件指针移动到新的位置,offset表示相对于whence的多少个字节的偏移量;offset:off为正往结束方向移动,为负往开始方向移动whence不同的值代表不同含义:0: 从文件头开始计算(默认值)1:从当前位置开始计算2:从文件尾开始计算 |
tell() | 返回文件指针的当前位置 |
truncate([size]) | 不论指针在什么位置,只留下指针前size个字节的内容,其余全部删除;如果没有传入size,则当指针当前位置到文件末尾内容全部删除 |
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区内容写入文件,同时关闭文件,释放文件对象相关资源 |