【python】20_IO编程之文件操作

【摘要】本博文介绍的文件的基本操作(读、写)以及文件的关闭

1.何为 IO?

所谓IO在计算机中即为Input和Output。我们都知道内存和CPU的速度远高于外设速度通常程序和运行时数据都存储在内存中,由CPU这个超快的计算核心来执行。凡是涉及到数据交换的地方都需要IO接口。
IO编程中,Stream流是个重要概念。Input Stream是数据从外设(磁盘、网络)流进内存,Output Stream是数据从内存流到外面去。注意只能单向流动。当然如果是浏览网页,我们不仅需要向网站服务器发送访问请求(Output Stream),也需要接收网站服务器发来的网页内容(Input Stream),这样至少需要两个数据流。
又由于内存与外设速度的严重不匹配,例如要将100M数据写入磁盘,CPU输入100M数据只需要0.01s,而磁盘接收这100M数据需要10s。那这10s时间,如果CPU处于等待状态,即程序暂停执行后续代码,直到这100M数据在10s后写入磁盘了,再继续执行后续代码,这种模式成为同步IO;如果CPU不等待,直接执行后续代码,这种模式成为异步IO。
异步IO编写程序性能远高于同步IO,但其缺点是编程模型复杂,有回调模式、轮询模式等。其复杂度远高于同步IO。操作IO的能力都是由操作系统提供的,每种编程语言都会把操作系统提供的低级C接口封装起来以便使用,我们本博文要学习的就是Python的IO编程接口。并且这里我们讨论的IO编程都是同步模式
【注】该段内容参考《廖雪峰Python教程》

2.文件操作

文件操作是IO编程的最基本操作,Python内置了读写文件的函数。
【注】
在这里插入图片描述
对文件操作分为三步:
Step1:打开文件
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。
open(文件名,访问模式) e.g. f = open(‘test.txt’, ‘w’)
如果文件不存在那么创建,如果存在那么就先清空,然后写入数据

# 打开文件doc/passwd(相对路径), /home/kiosk/pythonCode/doc/passwd(绝对路径)
#Windows系统下的绝对路径是用\分隔
#  默认打开是r权限
f = open('doc/passwd')

f就是通过请求操作系统打开的那个文件对象(即文件描述符)
打开的权限有以下几种方式(从帮助文档拷贝过来的)

========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
‘r’ open for reading (default)
‘w’ open for writing, truncating the file first(1).文件不存在则创建文件; 2).文件存在, 清空文件内容)
‘x’ create a new file and open it for writing
‘a’ open for writing, appending to the end of the file if it exists(1).文件不存在则创建文件; 2).文件存在, 不会清空文件内容)
‘b’ binary mode
‘t’ text mode (default)
‘+’ open a disk file for updating (reading and writing)
‘U’ universal newline mode (deprecated)

我们将常用的几种模式整理如下:

是否有读权限是否有写权限文件不存在,是否会创建文件文件操作是否会清空文件内容
ryesnonono
wnoyesyesyes
anoyesyesno
w+yesyesyesyes
a+yesyesyesno
r+yesyesnono

【注意】要读取二进制文件,比如图片、视频等等,用’rb’, ‘wb’, 'ab’等模式打开文件即可

print(f.mode)
#可以查看文件打开的权限

上面的open函数中我们没有指定打开权限,则默认权限为读权限r
在这里插入图片描述

f = open('doc/passwd','a+')
print(f.mode)

在这里插入图片描述
step2:对文件进行操作

读:
    f = open('doc/passwd','a+')
    print(f.read())

用a+的模式打开这个文件,该种模式具有读权限,执行f.read()读取文件内容如下:
在这里插入图片描述

写:
	f = open('doc/passwd','a+')
    f.write('hello')
	content = """
      		  learn Python
      		  master Python
	"""
	f.write(content)

因为这里我们打开文件的模式是a+,由于文件内本来就有内容,其指针直接在文件末尾添加我们写入的内容.。打开passwd文件显示如下在这里插入图片描述
使用a+模式,追加完内容之后,我们想要再打开看一下更新的内容。

print(f.read())

我们惊奇的发现读不到任何内容,但是打开该文件,内容确实存在。
在这里插入图片描述
这是由于,a+的模式追加完内容,文件指针在该文件的末尾,此时再想读取文件内容,指针从文件末尾开始读取,当然什么都不显示了。
使用tell()方法可以获取指针当前所在的位置。
使用seek()方法可以移动文件指针
seek(offset, from)有2个参数:
offset:偏移量
from:方向 0:表示文件开头; 1:表示当前位置; 2:表示文件末尾

在这里插入图片描述
第一次读取内容,我们发现读取不到。打印一下指针当前所在的位置,发现其在文件末尾。
使用seek()方法,将文件用到文件开头的0偏移处即(0,0),再次打印指针所在位置即可发现指针回到了文件开始。
在这里插入图片描述
Step3:关闭文件对象
方法一: 调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的

f.close()

方法二: Python引入了with语句来自动帮我们调用close()方法:
在这里插入图片描述

3.读写文件的函数使用

3.1 读操作
有三个函数read()、readline()、readlines()。在不同应用情境下使用的函数不一样。

read() 读取指定的字节,默认读取到文件末尾,返回的是一个字符串。我的电脑内存是4G,而如果我要读取的文件超过4G,那使用read()方法会一次性读取文件的全部内容,就会使内存爆掉。所以可以反复调用read(size)方法,每次最多读取size个字节的内容。

print(f.read(50))

可以看到,本次执行的结果只读取了50个字节的文件内容。
在这里插入图片描述

readline() 每次读取一行内容

print(f.readline())

可以看到执行该语句,只返回了文件的一行内容。
在这里插入图片描述
如果要读取大文件,代码实现如下:

while True:
    # 每次只读取一行内容, 如果不能读取到内容, break跳出;
    content = f.readline()
    if not content:
        break
    else:
        print(content, end='')

readlines() 读取文件所有的内容,并按行返回一个列表

print(f.readlines())

可以看到readlines返回的是包含文件所有内容的一个列表,列表中的每个元素为文件一行内容的字符串形式
在这里插入图片描述
可以使用如下方式查看内容:

for line in f.readlines():
    print(line)

在这里插入图片描述
但是注意到字符串最后的一个字符是\n,因此会换行。如果想要不换行的话,使用之前字符串学习过的strip()去掉广义的空格。

for line in f.readlines():
    print(line.strip())

在这里插入图片描述
即可。

【补充】
我们通过参数检测可以得知,文件是一个可迭代对象。可迭代对象都可以使用for循环。

from collections import Iterable
filename = 'date.pkl'
print(isinstance(filename,Iterable))

结果:
在这里插入图片描述
因此还可以使用下面方法读取文件:

filename = '1.txt'
with open (filename) as f:
    #用enumerate可以打印出索引及值,也可以不用enumerate()
    for index,content in enumerate(f):
        print('第%s行' %(index),content.strip())

结果:
在这里插入图片描述

关于这三个函数的如何选择,有以下建议:如果是小文件,read()一次读取即可;如果不确定文件大小,反复调用read(size)读取指定字节的内容;如果是大文件,调用readline()或readlines()

3.2 写操作
写操作有两个方法,write()和writelines()
写文件和读文件是一样的,唯一区别是注意调用open函数时,传入的模式要支持写权限。
write() 是从指针所在位置写入,写入是字符串内容
writelines() 是将列表里面的每个元素写入文件中

f.writelines(['第一个\n', '第二个\n'])

在这里插入图片描述

4. 文件的关闭

方法一: 调用close()方法关闭文件。文件使用完毕后必须关闭。
原因1:因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。
原因2:当我们写文件时,操作系统往往不会立即把数据写入磁盘中,而是放在内存里缓存起来,空闲的时候再慢慢写入。只有调用close()方法,操作系统才保证把没有写入的数据全部写入磁盘。如果忘记使用close(),后果就是数据可能只写了一部分到磁盘中,剩下的丢失了。因此用with语句更为保险。
方法二: Python引入了with语句来自动帮我们调用close()方法。

with语句工作原理:
python中的with语句使用于对资源进行访问的场合
保证不管处理过程中是否发生错误或者异常都会自动执行规定的(“清理”)操作,释放被访问的资源
比如有文件读写后自动关闭、线程中锁的自动获取和释放等。

【补充】
file对象还有两个属性,之前介绍了file.mode,返回被打开文件的访问模式。
剩下两个为:
file.closed,返回true如果文件已经关闭,否则返回false;
file.name,返回文件的名称

with open('doc/passwd') as f:
    print("with语句里面:", f.closed)
    print(f.read(10))
print("with语句外面:", f.closed)

这里我们使用file.closed方法,查看一下with语句是否有帮我们自动调用close()方法
在这里插入图片描述
File对象的属性:
在这里插入图片描述
File对象的常用方法:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值