前言
按文件中数据的组织形式可以把文件分为普通文本文件、二进制文件两大类。
所谓文本文件即用普通文本编辑器能正常显示的文件,有若干文本行组成,通常每行以换行符结尾。二进制文件以bytes进行存储的文件。无法被普通编辑器编辑,不能被直接理解。
一、文件对象
由open函数打开的文件对象,一般通过这个对象对文件内容进行读取、写入等操作。当然操作完成必须要关闭。
内置函数open
文件对象名=open(file, mode='r', buffering=None, encoding=None,
errors=None, newline=None, closefd=True)
对于open函数参数的补充说明:
- mode:模式
模式 | 说明 |
---|---|
r | 只读 |
rb | 用二进制打开文件进行读,一般用于非文本文件 |
r+ | 同时具有读和写的功能,默认光标一开始停在开头,当进行一个操作后(无论是读还是写)光标将自动移动到末尾.写的功能如果在末尾就是添加 |
rb+ | 略 |
w | 写入文件,但会清除原文本内容 |
wb | 写入二进制文件,但会清除原文本内容 |
W+ | 读写操作,先清空文本,再读 |
wb+ | 略 |
a | 追加,不会清空原文本内容, |
ab | |
a+ | 读追加写,不会清除文本原内容 |
ab+ |
补充:open其实还存在一个x模式,该模式只在文件不能存在时执行操作,存在则报错。
with open('file.txt','x') as f:
f.write('test')
- encoding:文本编码方式。文件的读取和写入采用的都是系统默认的文本编码方式。我们可以sys.getdefaultencoding()查看默认编码方式。
- errors: 有时候我们依然会不可避免的遇到未知编码的文件导致读取失败,就可以使用open函数提供error参数来对错误执行处理【值:replace替换、ignore忽略、strict报错】
- newline:默认情况下,python工作在通用换行符模式下,即所有常见换行格式均可识别出来。在读取时会将换行符转换成/n字符。输出时,又会将/n转换为当前系统默认的换行符。如果不想要这种编译行为的话open函数提供一个newline=’’的参数。
- buffering:设置文件缓冲。全缓冲 : open函数的buffering设置>1的整数n,n为缓冲区大小。行缓冲 : open 函数的buffering设置为1, 碰到换行就会将缓冲区的写入磁盘。【只适用于文本模式】无缓冲 : open 函数的buffering设置为0 有输入就写入磁盘。[只适用于二进制模式]
- closed: closefd的取值,是与传入的文件参数有关,默认情况下为True,传入的file参数为文件的文件名,取值为False的时候,file只能是文件描述符,什么是文件描述符,就是一个非负整数,在Unix内核的系统中,打开一个文件,便会返回一个文件描述符。
文件对象属性说明
- closed:判断文件是否关闭
- mode:返回文件的打开模式
- name:返回文件的名称
文件对象的常用方法
- flush()把缓冲区的内容写入文件
- close()把缓冲区的内容写入文件,同时关闭文件,释放文件对象。当文件对象处在上下文管理器环境中时,不需要使用此方法。
- read([size]),从文件中读取size个字符的内容作为结果返回,默认是全部读取。如果文件较大如你只有4G内存,但数据却有5G,不建议使用。可以考虑下面两种方法。
- readline:读取下一行,使用生成器方法。 readlines:读取整个文件到一个迭代器以供我们遍历。
- seek(offset,where=0)移动文件指针,offset相对于where的位置。where【0文件头,1当前位置,2文件尾】
- tell()告诉文件指针的位置。 writte()把字符串写入文件,如果需要换行末尾要添加\n
- writtelines()可以把字符串写入文件,它还接受由字符串列表元组,把它的元素写入文件中
对open函数使用的一些说明
- 将输出重定向到一个文件中去
with open('hello1.txt','x')as f:
print("hello",file=f)
- open函数的rb、wb模式为我们提供二进制的读写,读取二进制数据时,所有数据以字节串的形式返回。写入数据时,数据必须是以对象的形式来提供,而且该对象可以将数据以字节形式暴露出来。
在做索引和迭代操作时,字节串会返回代表该字节的整数值而不是字符串。
3.字符串上执行IO操作
import io
s=io.StringIO("onlyread")
s.write("onlygetvalue")
print(s.getvalue())#读
4.读写压缩数据文件
当我们需要读写压缩文件gzip、bz2格式压缩文件时,使用内建函数open已经不太行可以使用使用gzip、bz2模块自带的open函数【与普通open函数无差别】
序列化python对象
我们时常需要将python对象序列化字节流,这样就可以将其保存在文件中或进行传输。
序列化最常用的做法就是使用pickle模块
import pickle
class ClassTest():
def __init__(self):
pass
with open("testpickle.txt","wb") as f:
pickle.dump(ClassTest,f)
补充;其中dump、load方法存储或获取字节流。dumps、loads方法将对象转化成字符串/反过来。值得注意的是不能对非受信任数据pickle.load()。因为pickle会自动加载模块、创建实例。这意味着python解释器有机会执行任意代码命令。某些特定的对象是无法进行pickle操作的,但可以通过设置_getstate_和_setstate_方法。【dump会调用getstate来得到一个可以被pickle处理的对象】
概念的补充
缓冲区
缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。 缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。
为什么要引入缓冲区
比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。 又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。 现在您基本明白了吧,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。
缓冲区的类型
缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。
1、全缓冲 在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
2、行缓冲 在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。
3、不带缓冲 也就是不进行缓冲
参考:百度、cookbook、高级编程