注册 登录
Python基础教程

第一章: 环境搭建,安装Python

第二章: 挑选一款趁手的IDE

第三章: 计算机基础知识

第四章: 命令行基础知识

第五章: 从全局把握Python

第六章: Python语言基础

第七章: Python流程控制

第八章: Python数据类型与运算

第九章: Python字符串类型

第十章: Python列表类型

第十一章: Python元祖类型

第十二章: Python字典类型

第十三章: Python集合类型

第十四章: Python函数处理

第十五章: Python文件处理

第十六章: Python面向对象

第十七章: Python异常处理

第十八章: Python模块处理

第十九章: Python项目实战

首页 > Python基础教程 > 第十五章: Python文件处理 > 15.3节:文件读写的高级操作

15.3节:文件读写的高级操作

薯条老师 2020-05-24 08:35:36 224159 0

编辑 收藏

广州番禺Python, Java小班周末班培训

薯条老师的线下Python,Java小班周末班已经开课了,培训的课程有Python爬虫,Python后端开发,Python办公自动化,Python大数据分析,Java后端开发。授课详情请点击:http://chipscoco.com/?cate=6

15.3.1 文件的读写缓冲区

文件的读写缓冲区对应的是内存中的一块缓冲区:在对文件执行写操作时,会先将数据写到这个缓冲区,缓冲区写满以后再刷新到磁盘。在对文件执行读操作时,会先将文件的一部分数据预读到这块内存缓冲区,然后再从这块缓冲区里进行读取。

为什么需要这么一块内存缓冲区?

因为在内存中进行读写远快于直接在磁盘中进行读写,所以在写入的时候,先写到内存缓冲区,当数据量大于内存缓冲区的容量时,再一次性刷新到磁盘。读取也是一样的道理,先将磁盘文件中的一批数据预读到内存里来,后续读取的时候直接在内存缓冲区里进行读操作,大大提高了读取的性能。

(1) 文件流对象的flush方法
执行flush方法会手动地刷新内存缓冲区。
代码实例:

# __desc__ = 执行文件流对象的flush方法对缓冲区进行手动刷新
 
# 执行open方法获取一个文件流对象,使用w模式来进行写操作
file_stream = open("happy.txt", "w")
 
# 执行文件流对象的write方法来写入数据
# 返回值为写入的字符数
characters = file_stream.write("I am so happy")
 
"""
在程序中已经往文件里写入了数据,但在桌面中打开该文件时,
文件是一个空文件,因为数据只是被写入缓冲区
"""
 
# 执行flush方法手动刷新
file_stream.flush()
# 执行flush方法手动刷新以后,打开该文件会看到被写入的数据
 
# 执行close方法时,也会对缓冲区进行刷新
在open方法中有一个buffering参数,当给buffering参数传递0时,会关闭这个内存缓冲区,该操作只适用于二进制模式。传递1时设置行缓冲模式,只能用于文本模式。所谓的行缓冲是指一行缓冲的大小,这里的一行以行尾的换行符来进行标识。传递的值大于1时表示设置固定的缓冲区大小。

代码实例:

# __desc__ = 给buffering参数传递0,关闭缓冲区
 
# 执行open方法获取一个文件流对象,使用w模式来进行写操作
# 关闭缓冲区时,必须是二进制模式,所以模式为wb,表示以二进制模式进行写操作
file_stream = open("happy.txt", "wb", buffering=0)
 
# 执行write方法来写入数据
# 以二进制模式进行读写时,参数为bytes类型,通过字符串类型的encode方法进行转换
file_stream.write("I am so happy".encode())
 
# 关闭缓冲区以后,无需手动刷新,用编辑器打开该文件时,会立即看到写入的数据

15.3.2 文件的指针与定位

可以把文件指针形象地理解为箭头,一开始这个箭头指向文件的首行,应用程序读取文件时,从箭头指向的位置处开始读取。每读完一行,箭头就下移一行。
(1) file_stream.seek(offset, [from])

offset表示是偏移量,from表示从什么位置处开始进行定位,from的值为0时表示从文件头开始定位,为1时表示从当前位置开始定位,为2时表示从文件尾开始定位。from的值默认为0。如需从当前位置进行定位,必须以二进制模式来打开文件。

代码实例

# __desc__ = 执行seek方法对文件进行定位
 
# 执行open方法获取一个文件流对象,使用r模式进行读操作
file_stream = open("happy.txt", "r")
 
content = file_stream.read()
 
# 再次执行read方法读取时,读取到的是空数据
# 因为文件指针已经定位到文件尾
content = file_stream.read()
 
 
# 通过seek方法将指针定位到文件头
file_stream.seek(0, 0)
# 然后再调用read方法来进行读取,可以读取到文件中的内容
content = file_stream.read()

15.3.3 指定文件编码

在执行open函数获取文件流对象时,可以通过encoding参数来指定文件读写时的编码。

现在同学们通过以下步骤来进行操作,以理解encoding参数:
(1) 创建utf-8编码的文件
在D盘Python3-learning目录中创建encoding.txt文件,用记事本打开并输入“薯条橙子”四个中文字符,然后以UTF-8格式进行保存。

(2) 在程序中打开encoding.txt

代码实例:

# __desc__ = 以指定编码读取文件数据
 
# 读取时通过encoding参数指定utf-8编码
file_stream = open("D:\python3-learning\encoding.txt", "r", encoding= "utf-8")
content = file_stream.read()
print(content)
 
"""
程序的输出为:
'\ufeff薯条橙子'
"""
程序输出的\ufeff是字节顺序标记符BOM,从输出可知,由于文件的编码模式与我们在open方法中指定的编码模式一致,所以没有抛出任何异常,能读取到文件内容。

(3) 以ascii编码读取文件

现在以ascii编码读取文件内容:

file_stream = open("D:\python3-learning\encoding.txt", "r", encoding= "ascii")
content = file_stream.read()
在执行上文代码的过程中,系统抛出了异常信息:UnicodeDecodeError:'ascii'codec can't decode byte 0xef in position 0。因为磁盘中的encoding.txt文件是以utf-8进行编码的,而我们在open函数中指定的是ascii编码器,ascii编码器只限于对ascii字符进行编解码,所以解码失败。

(4) 以utf-8编码读取ascii编码的文件
继续在D盘Python3-learning目录中创建happy.txt文件,输入内容为happy,然后以ascii编码的方式进行保存。

代码实例:

# __desc__ = 以utf-8编码来读取ascii编码的文件
 
file_stream = open("D:\Python3-learning\happy.txt", "r", encoding= "utf-8")
content = file_stream.read()
print(content)
 
"""
程序的输出为:
'happy'
"""
程序能正常读取文件中的内容,没有抛出异常。因为utf-8字符集涵盖了ascii字符集,所以使用utf-8编码来读取文件时,能正确的编解码,而不会抛出异常信息。对于其它的编码方式,也是同样的原理。至于写入操作,就是以什么样的数据编码方式对文件内容进行写操作,如果与文件本身的编码方式不兼容,就会抛出异常信息。

15.3.4 对文件读写进行错误处理

open方法中的errors参数,用来控制出现编码和解码的错误时该如何处理。errors参数只能用于文本模式。

image.png

代码实例:

# __desc__ = 通过errors参数对错误进行处理
 
# happy.txt以ascii进行编码,指定encoding的参数为gbk编码
file_stream = open("D:\python3-learning\encoding.txt", "r", encoding= "gbk")
 
# 对文件进行读取时,Python解释器会抛出异常
content = file_stream.read()
 
# 指定ignore参数可以忽略编解码错误
file_stream = open("D:\python3-learning\encoding.txt", "r", encoding= "gbk", errors="ignore")
 
# 忽略读取过程中的编解码错误
content = file_stream.read()

15.3.5 知识要点

(1) 在内存中进行读写远快于直接在磁盘中进行读写,所以写入的时候,先写到内存缓冲区,当数据量大于内存缓冲区的阈值时,再一次性刷新到磁盘。读取也是一样的道理,先将磁盘文件中的一批数据预读到内存里来,后续读取的时候直接在内存缓冲区里进行读操作,大大提高了读取的性能。

15.3.6 高薪就业班

(1) Python后端工程师高薪就业班,月薪10K-15K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪10K-20K, 免费领取课程大纲
(4) Python大数据工程师就业班,月薪12K-25K,免费领取课程大纲

扫码免费领取学习资料:



欢迎 发表评论:

请登录

忘记密码我要注册

注册账号

已有账号?请登录