8.1 读写文件
8.1.1 打开和关闭文件
要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符:
>>> f = open('new.txt', 'r')
第一个参数为文件名,也可以加入路径,例如:'d:\new.txt',由于反斜线\可能会跟后面的字符形成转义字符,所以可以采用下面两种写法:
r'd:\new.txt'
'd:\\new.txt'
第二个参数代表打开的处理模式:标示符'r'表示读,这样,我们就成功地打开了一个文件。
打开方式种类如下:
| 处理模式 | 描述 |
|---|---|
| r | 以只读模式打开文件,并将文件指针指向文件头;如果文件不存在会报错 |
| w | 以只写模式打开文件,并将文件指针指向文件头;如果文件存在则将其内容清空,如果文件不存在则创建 |
| a | 以只追加可写模式打开文件,并将文件指针指向文件尾部;如果文件不存在则创建 |
| 加上+ | 打开文件同时支持输入输出 |
| 加上b | 读写二进制文件(默认是t,表示文本) |
以'w'模式写入文件时,如果文件已存在,会直接覆盖(相当于删掉后新写入一个文件)。如果我们希望追加到文件末尾时,可以传入'a'以追加(append)模式写入。
调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:
>>> f.close()
8.1.2 with关键字
使用open()和close()函数可以打开和关闭文件,但是如果代码中出现意外,在执行close()函数之前程序就退出,文件将不会关闭,这可能会导致数据未能写入或者文件内容受损。
这时可以通过with关键字解决文件的关闭问题,例如:8.1-file.py
with open(r'new.txt') as f:
print(f.read())
with关键字后面的open()函数打开文件,并将文件对象给后面的代码块使用,并没有调用close()函数关闭文件。这时,关闭文件的操作由Python解释器执行,执行完语句后,即使在处理行时遇到问题,文件 f 也始终会被关闭。结果为:
+++++++++++
Python News
+++++++++++
注意:只能在with关键字后面的代码块中操作文件读写,with后面语句中不能读写文件,因为文件已经关闭了。
8.1.3 读取文件
按字节读取:read()函数会一次性读取文件的全部内容,并将其作为字符串返回,如果文件很大,会占用很大内存,所以可以反复调用read(size)方法,每次最多读取size个字节的内容。
按行读取:调用readline()可以每次读取一行内容,而调用readlines()一次读取所有内容并按行返回list。
也可以直接按行遍历文件对象,内存使用更高效:
for line in f:
print(line.strip()) # 把末尾的'\n'删掉
如果文件很小,read()和readlines()一次性读取最方便;如果不能确定文件大小,可以反复调用read(size)或迭代读取每一行比较节省内存。
8.1.4 写入文件
写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符'w'或者'wb'表示写文本文件或写二进制文件:
# 写入文件
filename = r'new1.txt'
with open(filename, 'w') as f:
f.write('write OK' + '\n') # 写入时,行末需要加入换行符,否则不会换行。
另一种写入函数是writelines,传入字符串的列表进行写入。
8.1.5 定位读写
可以使用seek函数实现文件里的定位读写,seek函数的声明为:
seek(offset, from_what)
offset参数:偏移量。
from_what:偏移量的起始位置。0:文件开头;1:当前位置;2:文件结尾。默认为0
在文本文件中,即没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置,从文件当前位置或者结尾计算时就会引发异常。
可以加入b模式以二进制打开文件,以便从当前位置或文件结尾进行偏移定位。
例如:
>>> f = open('test.txt', 'r+')
>>> f.read()
'0123456789\n'
>>> f.seek(0)
0
>>> f.read(1)
'0'
>>> f.read(1)
'1'
>>> f.seek(4)
4
>>> f.read(1)
'4'
>>> f.read(1)
'5'
>>> f.seek(2, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
io.UnsupportedOperation: can't do nonzero cur-relative seeks
>>> f = open('test.txt', 'rb+')
>>> f.read(1)
b'0'
>>> f.seek(3, 1)
4
>>> f.read(1)
b'4'
>>> f.seek(-2, 2)
10
>>> f.read(1)
b'\r'
>>> f.read(1)
b'\n'