简介
数据库文件、图像文件、音频和视频文件、可执行文件、Office文档、动态链接库文件等,都以文件的形式存储在不同的存储设备(如磁盘、U盘、光盘、云盘等)上,按文件中数据的组织形式可以把文件分为文本文件和二进制文件两大类
文本文件
文本文件存储的是常规字符串,由若干文本行组成,通常每行以换行符 “\n” 结尾。常规字符串是指记事本之类的文本编辑器能正常显示、编辑并且正常阅读和理解的字符串,如英文、汉字、数字字符串等。拓展名为txt、log、ini的文件都属于文本文件
二进制文件
常见的如图形图像文件、音频和视频文件、可执行文件、资源文件、各种数据库文件、各类Office文档等都属于二进制文件。二进制文件把信息以字节串(bytes)进行存储,无法用记事本或其他普通字处理软件直接进行编辑,需要使用对应的软件进行解码后读取、显示、修改或执行
文件对象常用方法与属性
无论是文本文件还是二进制文件,其操作流程基本都是一致的,即首先打开文件并创建文件对象,然后通过该文件对象对文件内容进行读取、写入、删除、修改等操作;最后关闭并保存文件内容。Python内置了文件对象,通过open()函数既可以指定模式打开指定文件并创建文件对象,该函数用法为:
open(file, mode = “r”, buffering = -1, encoding = None, errors = None, newline = None, closefd = True, opener = None)
该函数的主要参数含义如下:
1、file
参数file指定要打开或创建的文件名称,如果该文件不在当前目录中,则需要指定完整路径,为了减少完整路径中 “” 符号的输入,可以试音原始字符串,或在路径的双引号前加上 r
2、mode
参数mode指定打开文件后的处理方式,如“只读”、“只写”、“读写”,“追加”、“二进制只读”、“二进制读写”等,默认为文本只读模式。以不同方式打开文件时,文件指针的初始位置略有不同,例如,以“只读”和“只写”模式打开文件时文件指针的初始位置是文件头,而以“追加”模式打开文件时,则文件指针的初始位置为文件尾
3、buffering
参数buffering指定读写文件的缓存模式,数值0(只在二进制模式中可以用)表示不缓存,数值1(只在文本模式中可以用)表示使用行缓存模式,大于1的数字则表示缓存区的大小,默认值为 -1 。当使用默认值 -1 时,二进制文件和非交互式文本文件以固定大小的块为缓存单位,等价于 io.DEFAULT_BUFFER_SIZE,交互式文本文件(isatty()方法返回True)采用行缓存模式
4、encoding
参数encoding指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式。Windows默认使用GBK进行编码,而Python3默认使用UTF-8进行编码,所有最好在定义时就设置使用UTF-8进行编码,否则出现乱码
5、newline
参数newline只适用于文本模式,取值可以是None、"、“\n”、“\r”、“\r\n” 中的任何一个,表示文件中新行的形式
如果执行正常,open()函数返回一个可迭代的文件对象,通过该文件对象可以对文件进行读写操作,如果指定文件不存在、访问权限不够、磁盘空间不够或其他原因导致创建文件对象失败则抛出异常。当对文件内容操作完以后,一定要关闭文件对象,,这样才能保证所做的任何修改都确实被保存到文件中
模式 | 说明 |
---|---|
r | 读模式(默认模式,可省略),如果文件不存在则抛出异常 |
w | 写模式,如果文件已存在,会先清空原有内容,再写入新文本 |
x | 写模式,创建新文件,如果文件已存在则抛出异常 |
a | 追加模式,不覆盖文件中原有内容 |
b | 二进制模式(可与其他模式组合使用) |
t | 文本模式(默认模式,可省略) |
+ | 读、写模式(可与其他模式组合使用) |
属性 | 说明 |
---|---|
closed | 判断文件是否关闭,若文件已关闭则返回True |
mode | 返回文件的打开模式 |
name | 返回文件的名称 |
方法 | 功能说明 |
---|---|
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区的内容写入文件,同时关闭文件,并释放文件对象 |
read([size]) | 从文件中读取size个字节或字符的内容作为结果返回,如果省略size则表示读取所有内容 |
readline() | 从文本文件中读取一行内容作为结果返回 |
readlines() | 把文本文件中的每行文本作为一个字符串存入列表中,返回该列表 |
seek(offset[, whence]) | 把文件指针移动到新的位置,offset表示相对于whence的位置。whence为0表示从文件头开始计算,1表示从当前位置开始计算,2表示从文件尾开始计算,默认为0 |
tell() | 返回文件指针的当前位置 |
truncate([size]) | 删除从当前指针位置到文件末尾的内容。如果指定了size,则不论指针在什么位置都只留下前size个字节,其余的删除 |
write(s) | 把字符串s的内容写入文件 |
writelines(s) | 把字符串列表写入文本文件,不添加换行符 |
writable() | 测试当前文件是否可写 |
readable() | 测试当前文件是否可读 |
文本文件操作
向文本文件中写入内容
str = "hello python\n文本文件的服务方法\n文本文件的写入方法\n"
#打开文件,如果该文件不存在则创建,指定编码格式为“utf-8”
f = open("sample.txt", "a+", encoding="utf-8")
#写入文件内容
f.write(str)
#关闭文件
f.close()
文件操作一般都要遵循“打开文件————读写文件————关闭文件”的标准套路,但是如果文件读写操作代码引发了异常,很难保证文件能够被正确关闭,使用上下文管理关键字 with 可以避免这个问题。关键字 with 可以自动管理资源,不论因为什么原因(哪怕是代码引发了异常)跳出with块,总能保证文件被正确关闭,并且可以在代码块执行完毕后自动还原进入该代码块时的现场,常用于文件操作、数据库链接、网络通信连接等场合。有了 with ,再也不用担心文件没有关闭了。
str = "hello python\n文本文件的服务方法\n文本文件的写入方法\n"
with open("sample.txt", "a+", encoding="utf-8") as f:
f.write(str)
另外,上下文管理语句 with 还支持下面的用法:
with open("sample.txt", "r", encoding="utf-8") as src, open("test_new.txt", "w", encoding="utf-8") as det:
det.write(src.read())
二进制文件操作
必须正确理解二进制文件的结构和序列化规则,然后设计正确的反序列规则,才能准确地理解二进制文件内容
序列化是指将数据结构或对象状态转换成可取用格式(例如将内存中的变量等数据存放到磁盘中某个文件,或存于缓冲,或经由网络中发送),以留待后继在相同或另一台计算器环境中,能恢复撤销前的状态的过程。这个过程反过来则为“反序列化”,如将磁盘中的文件转换为内存中数据结构或者对象的过程
Python 中常用的序列化模块有 struct、pickle、shelve、marshal和json,其中JSON常用在文本信息的序列化
使用pickle模块读写二进制文件
Python标准库pickle提供的dump()方法用于将数据进行序列化并写入文件(dump()方法的protocol参数为True时可以实现压缩的效果),而load()用于读取二进制文件内容并进行反序列化,还原为原来的信息
pickle.dump(obj, file [, protocol])
- 功能:将obj对象序列化存入已经打开的file中
- obj : 序列化的对象
- file:序列化保存到的类文件对象。file需要支持write()接口, file可以是一个以’w’方式打开的文件或者一个StringIO对象或者其他任何实现write()接口的对象。如果protocol>=1,文件对象需要是二进制模式打开的。
- protocol:序列化使用的协议,可选参数,默认为0,如果设置为1或True,则以高压缩的二进制格式保存序列化对象,否则以ASCII格式保存
pickle.load(file)
- 功能:将file中的对象反序列化读出
- file:对应于上面dump方法中的file参数。file需要支持read()接口,接受一个整数位参数;同时支持readline()接口,无需输入参数,比如StringIO。可以是一个以二进制读模式打开的文件对象
dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。
import pickle
num = 4
i = 2333
str = "使用pickle模块读写二进制文件"
pickle_list = [20181016, "hello python"]
pickle_dict = {"h" : "hello", "p" : "python"}
num_dict = (233, "哈哈哈")
f = open("sample_pickle.dat", "wb")
try:
pickle.dump(num, f) #对象个数
pickle.dump(i, f) #写入整数
pickle.dump(str, f) #写入字符串
pickle.dump(pickle_list, f) #写入列表
pickle.dump(pickle_dict, f) #写入字典
pickle.dump(num_dict, f) #写入元组
except:
print("写文件异常")
finally:
f.close()
使用pickle模块读取写入二进制文件内容
import pickle
f = open("sample_pickle.dat", "rb")
for i in range(6):
n = pickle.load(f)
print(n)
f.close()
####################################
4
2333
使用pickle模块读写二进制文件
[20181016, 'hello python']
{'h': 'hello', 'p': 'python'}
(233, '哈哈哈')
pickle.dumps(obj [, protocol])
- 功能:将obj对象序列化为bytes(二进制字符串)形式,但不存入文件中,而是将所得到的转换后的数据以二进制字符串的形式返回
- obj:序列化的对象
- protocol:默认值为0,如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本,同dump
pickle.loads(bytes)
- 功能:从bytes中读出序列化前的obj对象
- bytes:存放序列化对象的变量
cPickle是pickle的一个更快的C语言编译版本