Python进阶教程m2–文件读写

原文链接:http://www.juzicode.com/archives/621

文件读写是计算机语言无法回避的话题,这篇文章将介绍文件的基本读写操作。通常文件分为文本文件和二进制文件,Python也支持这2种文件的读写操作。

打开文件

打开文件使用open()函数:文件对象fileobj=open(‘文件名称’,‘打开模式’),如果打开文件成功,就会创建一个文件对象,后面的读出、写入和关闭就在该对象上进行。

文件的打开模式有下表的几种模式,其中是否带字母“b”决定了访问文件的方式是采用文本方式访问还是二进制方式访问(带字母“b”),如果采用文本方式访问时,需要指定文件的编码方式,默认跟随系统设置的编码方式;二进制访问就是获取文件的每个字节的二进制数值,不存在类似文本的编码方式。

打开模式文件类型方式对已有文件影响如果文件不存在备注
r文本只读抛异常write等方法不可用
rb二进制只读抛异常write等方法不可用
r+文本读写追加抛异常 
rb+二进制读写追加抛异常 
w文本只写覆盖并新建新建read等方法不可用
wb二进制只写覆盖并新建新建read等方法不可用
w+文本读写覆盖并新建新建因为覆盖原来文件,read等方法获取到原文件的内容
wb+二进制读写覆盖并新建新建因为覆盖原来文件,read等方法获取到原文件的内容
a文本追加追加到最后新建read等方法不可用
ab二进制追加追加到最后新建read等方法不可用
a+文本读写追加到最后新建 
ab+二进制读写追加到最后新建

下面这个例子试图以文本只读模式打开一个不存在的文件,会出现抛异常,提示文件不存在“No such file or directory”:

fileobj=open('example-r1.txt','r')
print('fileobj',fileobj)

==========结果==========
Traceback (most recent call last):
  File "E:\juzicode\py3study\m02-文件\open-打开文件.py", line 12, in <module>
    fileobj=open('example-r1.txt','r')
FileNotFoundError: [Errno 2] No such file or directory: 'example-r1.txt'

如果使用“w”模式打开文件,试图调用read()方法会导致异常:

下面的这个例子是用“r”和“rb”模式打开2个文件,从打印文件对象的信息可以看到,“example-r1.txt”是用“r”模式打开,调用open()函数时没有显式说明编码方式,从这个对象信息中可以看到默认的编码方式是cp936,这是跟随中文操作系统默认的GBK编码方式。而打开“example-r2.txt”文件是二进制方式,是不需要表明编码方式的。

fileobj=open('example-r1.txt','r')
print('fileobj',fileobj)

fileobj=open('example-r2.txt','rb')
print('fileobj',fileobj)

==========结果==========
-----欢迎来到www.juzicode.com
-----公众号: juzicode/桔子code

fileobj <_io.TextIOWrapper name='example-r1.txt' mode='r' encoding='cp936'>
fileobj <_io.BufferedReader name='example-r2.txt'>

关闭文件

使用完文件后要使用文件对象fileobj.close()方法关闭文件。

fileobj=open('example-r1.txt','r')
print('fileobj',fileobj)

fileobj.close() #关闭文件

当然在Python中还提供了一种比较“优雅”的打开文件的方式,不需要人为的显式调用close()方法关闭文件,使用with…as…语句:

with open('example-r2.txt','r') as fileobj:
    print('fileobj',fileobj)
    fileobj.read()

print('fileobj',fileobj)
fileobj.read()

==========结果==========
fileobj <_io.TextIOWrapper name='example-r2.txt' mode='r' encoding='cp936'>
fileobj <_io.TextIOWrapper name='example-r2.txt' mode='r' encoding='cp936'>
Traceback (most recent call last):
  File "E:\juzicode\py3study\m02-文件\close-关闭文件2.py", line 17, in <module>
    fileobj.read()
ValueError: I/O operation on closed file.

从上面的例子可以看出在with…as…缩进的代码块中,使用fileobj的read()方法是没有问题的,但是在with..as语句之后,再使用fileobj.read()方法时,抛ValueError异常提示文件已关闭,说明在with…as语句之外文件对象已经关闭了。

读文件

方法用途备注
read()尽可能多读出文件内容 
readline()每次读一行 
readlines()读所有行,读出内容为换行符为间隔分割的list 

下面这个例子就是用3种方法分别读出一个有4行文本内容的文件:

with open('example-r1.txt','r') as fileobj:
    content=fileobj.read()
    print('read()方法:\n',content)


with open('example-r1.txt','r') as fileobj:
    content=fileobj.readline()
    print('readline()方法:\n',content)

with open('example-r1.txt','r') as fileobj:
    content=fileobj.readlines()
    print('readlines()方法:\n',content)

==========结果==========
read()方法:
 www.juzicode.com
juzicode.com
公众号: 桔子code
公众号: juzicode

readline()方法:
 www.juzicode.com

readlines()方法:
 ['www.juzicode.com\n', 'juzicode.com\n', '公众号: 桔子code\n', '公众号: juzicode']

写文件

方法用途备注
write()写入内容 
writelines()写入list内容,不会在元素之间自动添加换行符。 

【注意】文件对象不存在writeline()方法!

写文本文件的例子:

对比readlines()方法,writelines()不会进行“逆操作”在list元素后添加换行符。

5 追加模式读出文件

用追加模式“a+”打开文件时,使用read()方法读出文件后再打印文件内容,发现“获取”到的值为空:

with open('example-a3.txt','a+',encoding='utf8') as fileobj:
    content=fileobj.read()
    print('read():\n',content) 

==========结果==========
read():

#打印的内容为空

使用“a”模式打开文件时调用read()方法会导致抛异常,而“a+”模式下read()方法可以使用只是没有得到预期的内容。是因为追加模式打开文件后,文件指针实际指向了文件的最后,所以read()方法获取不到文件内容,打开文件后就使用tell()方法可以看到文件指针实际已经指向了文件的最后,要获取文件内容可以使用seek(0)方法将文件指针指到文件的开头,再使用read()方法读出文件内容:

with open('example-a3.txt','a+',encoding='utf8') as fileobj:
    posi = fileobj.tell()  #获取当前文件指针位置
    print('tell():',posi)
    fileobj.seek(0)      #文件指针指向开始位置
    content=fileobj.read()
    print('read():\n',content)  
    
==========结果==========
tell(): 47
read():
 www.juzicode.com
微信公众号: 桔子code

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注