Python 也具有操作文件(I/O)的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。
有些数据需要在程序停止后保存,就需要将数据保存到文件中。
关于文件,它有两个关键属性,分别是“文件名”和“路径”。
注意,文件夹名称和文件名在 Windows 和 OS X 上是不区分大小写的,但在 Linux 上是区分大小写的。
在 Windows 上,路径书写使用反斜杠 “\” 作为文件夹之间的分隔符。但在 OS X 和 Linux 上,使用正斜杠 “/” 作为它们的路径分隔符。
将单个文件和路径上的文件夹名称的字符串传递给它,os.path.join() 就会返回一个文件路径的字符串,包含正确的路径分隔符。
import os
print(os.path.join('nginx-1.21.1', 'nginx.exe'))
import os
myFiles = ['accounts.txt', 'details.csv', 'invite.docx']
for filename in myFiles:
print(os.path.join('C:\\demo\\exercise', filename))
C:\demo\exercise\accounts.txt
C:\demo\exercise\details.csv
C:\demo\exercise\invite.docx
Python os.path 模块提供了一些函数,可以实现绝对路径和相对路径之间的转换,以及检查给定的路径是否为绝对路径。
调用 os.path.abspath(path) 将返回 path 参数的绝对路径的字符串,这是将相对路径转换为绝对路径的简便方法。
调用 os.path.isabs(path),如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。
调用 os.path.relpath(path, start) 将返回从 start 路径到 path 的相对路径的字符串。如果没有提供 start,就使用当前工作目录作为开始路径。
调用 os.path.dirname(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容;
调用 os.path.basename(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容。
调用 os.getcwd() 将返回当前工作目录。
调用 os.path.split() 将同时返回目录名和文件名。
举例:
print(os.getcwd()) # D:\study\python\BaseLearn\day01\learn12
print(os.path.abspath('nginx.conf')) # D:\study\python\BaseLearn\day01\learn12\nginx.conf
print(os.path.isabs('nginx-1.21.1\\nginx.exe')) # False
print(os.path.isabs('D:\\study\\python\\BaseLearn\\day01\\learn12')) # True
print(os.path.relpath('C:\\python', 'C:\\')) # python
print(os.path.relpath('C:\\python', 'C:\\java\\images')) # ..\..\python
path = 'C:\\Windows\\System32\\calc.exe'
print(os.path.dirname(path)) # C:\Windows\System32
print(os.path.basename(path)) # calc.exe
print(os.path.split(path)) # ('C:\\Windows\\System32', 'calc.exe')
检测给定的路径是否存在,以及它是文件还是文件夹:
path = 'C:\\Windows\\System32\\calc.exe'
print(os.path.exists(path)) # True
path02 = "D:\\Windows\\System32\\calc.exe"
print(os.path.exists(path02)) # False
file = 'D:\\nginx\\nginx.txt'
print(os.path.isfile(file)) # True
print(os.path.isdir(file)) # False
print(os.remove('a.txt')) # 删除同目录下的 a.txt 文件。
文件的应用级操作可以分为以下 3 步,每一步都需要借助对应的函数实现:
open() 函数用于创建或打开指定文件。
file = open(file_name [, mode='r' [ , buffering=-1 [ , encoding = None ]]])
open 函数支持的文件打开模式:
模式 | 意义 | 注意事项 |
---|---|---|
r | 只读模式打开文件,读文件内容的指针会放在文件的开头。 | 操作的文件必须存在。 |
rb | 以二进制格式、采用只读模式打开文件,读文件内容的指针位于文件的开头,一般用于非文本文件,如图片文件、音频文件等。 | |
r+ | 打开文件后,既可以从头读取文件内容,也可以从开头向文件中写入新的内容,写入的新内容会覆盖文件中等长度的原有内容。 | |
rb+ | 以二进制格式、采用读写模式打开文件,读写文件的指针会放在文件的开头,通常针对非文本文件(如音频文件)。 | |
w | 以只写模式打开文件,若该文件存在,打开时会清空文件中原有的内容。 | 若文件存在,会清空其原有内容(覆盖文件);反之,则创建新文件。 |
wb | 以二进制格式、只写模式打开文件,一般用于非文本文件(如音频文件) | |
w+ | 打开文件后,会对原有内容进行清空,并对该文件有读写权限。 | |
wb+ | 以二进制格式、读写模式打开文件,一般用于非文本文件 | |
a | 以追加模式打开一个文件,对文件只有写入权限,如果文件已经存在,文件指针将放在文件的末尾(即新写入内容会位于已有内容之后);反之,则会创建新文件。 | |
ab | 以二进制格式打开文件,并采用追加模式,对文件只有写权限。如果该文件已存在,文件指针位于文件末尾(新写入文件会位于已有内容之后);反之,则创建新文件。 | |
a+ | 以读写模式打开文件;如果文件存在,文件指针放在文件的末尾(新写入文件会位于已有内容之后);反之,则创建新文件。 | |
ab+ | 以二进制模式打开文件,并采用追加模式,对文件具有读写权限,如果文件存在,则文件指针位于文件的末尾(新写入文件会位于已有内容之后);反之,则创建新文件。 |
file = open('aa.txt', encoding='utf-8')
print(file) # <_io.TextIOWrapper name='aa.txt' mode='r' encoding='utf-8'>
输出了 file 文件对象的相关信息,包括打开文件的名称、打开模式、打开文件时所使用的编码格式。
注意,手动修改 encoding 参数的值,仅限于文件以文本的形式打开,也就是说,以二进制格式打开时,不能对 encoding 参数的值做任何修改,否则程序会抛出 ValueError 异常。
通常情况下、建议大家在使用 open() 函数时打开缓冲区,即不需要修改 buffing 参数的值。
file = open('aa.txt', encoding='utf-8')
print(file.closed) # False
print(file.encoding) # utf-8
print(file.name) # aa.txt
print(file.mode) # r
读取文件中数据的操作:
借助 open() 函数,并以可读模式(包括 r、r+、rb、rb+)打开的文件,可以调用 read() 函数逐个字节(或者逐个字符)读取文件中的内容。
如果文件是以文本模式(非二进制模式)打开的,则 read() 函数会逐个字符进行读取;反之,如果文件以二进制模式打开,则 read() 函数会逐个字节进行读取。
file.read([size])
file 表示已打开的文件对象;size 作为一个可选参数,用于指定一次最多可读取的字符(字节)个数,如果省略,则默认一次性读取所有内容。
f = open('aa.txt', encoding='utf-8')
print(f.read())
f.close()
黄金百战穿金甲,不破楼兰终不还。
古道黄昏瘦马,夕阳西下,小桥流水人家。
===================》
问君能有几多愁,恰是一江春水向东流。
通过使用 size 参数,指定 read() 每次可读取的最大字符(或者字节)数。
print(f.read(7)) # 黄金百战穿金甲
#以二进制形式打开指定文件,该文件编码格式为 utf-8
f = open("my_file.txt",'rb+')
byt = f.read()
print(byt)
print("\n转换后:")
print(byt.decode('utf-8'))
#关闭文件
f.close()
####################
b'Python\xe6\x95\x99\xe7\xa8\x8b\r\nhttp://c.biancheng.net/python/'
转换后:
Python教程
http://c.biancheng.net/python/
readline() 函数用于读取文件中的一行,包含最后的换行符“\n”。
file.readline([size])
f = open('aa.txt', encoding='utf-8')
print(f.readline()) # 黄金百战穿金甲,不破楼兰终不还。
readlines() 函数用于读取文件中的所有行,它和调用不指定 size 参数的 read() 函数类似,只不过该函数返回是一个字符串列表,其中每个元素为文件中的一行内容。
f = open('aa.txt', encoding='utf-8')
print(f.readlines())
['黄金百战穿金甲,不破楼兰终不还。\n', '古道黄昏瘦马,夕阳西下,小桥流水人家。\n', '===================》\n', '问君能有几多愁,恰是一江春水向东流。']
file.write(string)
在使用 write() 向文件中写入数据,需保证使用 open() 函数是以 r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。
file = open('aa.txt', 'w', encoding='utf-8')
file.write("写入一行新的数据。")
file.close()
再次查看 aa.txt 文件,内容为:写入一行新的数据。
如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象提供的 flush() 函数,它可以实现将缓冲区的数据写入文件中。
f = open("a.txt", 'w')
f.write("写入一行新数据")
f.flush()
对于以二进制格式打开的文件,可以不使用缓冲区,写入的数据会直接进入磁盘文件;但对于以文本格式打开的文件,必须使用缓冲区,否则 Python 解释器会 ValueError 错误。
使用 writelines() 函数,可以轻松实现将 a.txt 文件中的数据复制到其它文件中。
f = open('aa.txt', 'r')
n = open('bb.txt','w+')
n.writelines(f.readlines())
n.close()
f.close()
需要注意的是,使用 writelines() 函数向文件中写入多行数据时,不会自动给各行添加换行符。
上面例子中,之所以 b.txt 文件中会逐行显示数据,是因为 readlines() 函数在读取各行数据时,读入了行尾的换行符。
close() 函数是专门用来关闭已打开文件的。
使用 with as 操作已经打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
with 表达式 [as target]:
代码块
with open('aa.txt', 'a', encoding='utf-8') as f:
f.write("\n你好,星期六。")
# 写入一行新的数据。
# 你好,星期六。