python 读写文件之 open 和 with open() 详细解析
python 读写文件之 open 和 with open() 详细解析
文章目录
当我们讨论文件操作时,通常会涉及到open()和close()这两个函数。在Python中,open()函数用于打开一个文件,并返回一个文件对象,而close()函数用于关闭之前打开的文件。然而,在实际编程中,使用with open()语句是一种更安全、更简洁的方式来处理文件操作。下面将详细介绍这些概念。
1. open() 和 with open() 能打开不同的文件类型吗?
open() 和 with open() 在 Python 中都能用来打开各种类型的文件,包括文本文件和二进制文件。它们之间的主要区别在于文件处理的方式和资源管理
上,而不是它们能够打开的文件类型。
不论使用 open() 还是 with open(),你都可以打开以下类型的文件:
- 文本文件:
使用 ‘r’(读取模式)、‘w’(写入模式)、‘a’(附加模式)等文本模式来打开文件。 - 二进制文件:
使用 ‘rb’(读取二进制模式)、‘wb’(写入二进制模式)、‘ab’(附加二进制模式)等二进制模式来打开文件。
2. 文本文件和二进制文件的区别
2.1 文本文件 (Text Files)
文本文件是由一系列可打印的字符(如字母、数字、标点符号等)
组成,这些字符按照某种编码标准(如 ASCII、UTF-8 等)表示。文本文件的主要特点包括:
文本文件的例子包括纯文本文件(.txt)、源代码文件(如 .py、.java)、HTML 文件(.html)、Markdown 文件(.md)等。
2.2 二进制文件 (Binary Files)
非文本文件或二进制文件包含了不仅仅是可打印字符的信息,还包括了无法直接显示或解释的字节序列
。这类文件的特点包括:
区别
3. 读文件
3.1 使用 open() 和 close()
使用Python内置的open()函数,传入文件名和标示符:
>>> f=open(r'F:\jupyter notebook files\text files.txt','r') #标示符'r'表示读
如果文件不存在,open()函数就会抛出一个错误,并且给出错误码和详细的信息告诉你文件不存在:
>>> f=open(r'F:\jupyter notebook files\text.txt','r')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'F:\\jupyter notebook files\\text.txt'
调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示:
>>> contents=f.read()
>>> print(contents)
naruto
bleach
onepiece
最后需要调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:
>>> f.close()
由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。为了保证无论是否出错都能正确地关闭文件,我们可以使用try … finally来实现:
try:
f=open(r'F:\jupyter notebook files\text files.txt','r')
contents=f.read()
print(contents)
finally:
if f:
f.close()
输出如下:
naruto
bleach
onepiece
3.2 使用with open()
每次都写close()比较繁琐,Python引入with语句,这样能够确保最后文件一定被关闭,且不用手动再调用close方法,效果和前面的try … finally是一样的。
注意:
1、调用read()会一次性读取文件的全部内容
with open(r'F:\jupyter notebook files\text files.txt','r') as f:
contents=f.read()
print(contents)
输出如下:
naruto
bleach
onepiece
2、调用readline()可以每次读取一行内容
with open(r'F:\jupyter notebook files\text files.txt','r') as f:
a=f.readline()
print(a)
b=f.readline()
print(b)
c=f.readline()
print(c)
输出如下:
naruto
bleach
onepiece
3、调用readlines()一次读取所有内容并按行返回list
with open(r'F:\jupyter notebook files\text files.txt','r') as f:
a=f.readlines()
print(a)
输出入下:
['naruto\n', 'bleach\n', 'onepiece']
4. 写文件
调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件:
with open(r'F:\jupyter notebook files\text files.txt','w') as f:
a=f.write('attack on titan\n')
要写入特定编码的文本文件,请给open()函数传入encoding参数,将字符串自动转换成指定编码。
4.1 字符编码
要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:
with open(r'F:\jupyter notebook files\gbk.txt', 'r', encoding='gbk') as f:
a=f.read()
print(a)
输出如下:
gbk文本
遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
with open(r'F:\jupyter notebook files\gbk.txt', 'r', encoding='gbk',errors='ignore') as f: #注意errors='ignore'
a=f.read()
print(a)
4.2 读写方式列表
模式 | 描述 |
---|---|
r |
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w |
打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb |
以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ |
打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ |
以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
4.3 文件对象的属性
属性 | 描述 |
---|---|
file.read([size]) |
将文件数据作为字符串返回,可选参数 size 控制读取的字节数 |
file.readlines([size]) |
返回文件中行内容的列表,size 参数可选 |
file.write(str) |
将字符串写入文件 |
file.writelines(strings) |
将字符串序列写入文件 |
file.close() |
关闭文件 |
file.closed |
表示文件已经被关闭,否则为 False |
file.mode |
Access 文件打开时使用的访问模式 |
file.encoding |
文件所使用的编码 |
file.name |
文件名 |
file.newlines |
未读取到行分隔符时为 None ,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表 |
file.softspace |
为 0 表示在输出一数据后,要加上一个空格符,1 表示不加。这个属性一般程序员用不着,由程序内部使用 |
5.需要注意的点
open()
函数传入 encoding
参数。read()
将一次性读取文件的全部内容,如果文件有 10GB,内存就爆了,保险起见可以反复调用 read(size)
方法,每次最多读取 size
个字节的内容。readline()
可以每次读取一行内容,调用 readlines()
一次读取所有内容并按行返回 list。read()
一次性读取最方便;如果不能确定文件大小,反复调用 read(size)
比较保险;如果是配置文件,调用 readlines()
更方便。作者:迷路爸爸180