作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
基本文件操作
- 打开文件
在 Python 中,内置了文件(File)对象。在使用文件对象时,首先需要通过内置的 open() 方法创建一个文件对象,然后通过该对象提供的方法进行一些基本文件操作。open() 函数的基本语法格式如下:
file = open(fileName[,mode[,bufferung]])
file:被创建的文件对象;
fileName:要创建或打开的文件名称,需要使用单引号或双引号括起来。如果要打开的文件和当前文件在同一个目录下,那么直接写文件名即可,否则需要制定完整路径;
mode:可选参数,用于指定文件的打开模式,默认打开模式为只读(即r)。mode 参数的参数值说明如下表所示:
值 | 说明 | 注意 |
---|---|---|
r | 以只读模式打开文件,文件的指针将会放在文件的开头 | 文件必须存在 |
rb | 以二进制格式打开文件,并且采用只读模式,文件的指针将会放在文件的开头,一般用于非文本文件,如图片,声音等 | 文件必须存在 |
r+ | 打开文件后,可以读取文件的内容,也可以写入新的内容覆盖原有内容(从文件开头进行覆盖) | 文件必须存在 |
rb+ | 以二进制格式打开文件,并且采用读写模式,文件的指针将会放在文件的开头,一般用于非文本文件,如图片、声音等 | 文件必须存在 |
w | 以只写模式打开文件 | 文件存在,则将其覆盖,否则创建新文件 |
wb | 以二进制格式打开文件,并且采用只写模式,一般用于非文本文件,如图片、声音等 | 文件存在,则将其覆盖,否则创建新文件 |
w+ | 打开文件后,先清空原有内容,使其变为一个空的文件,对这个空文件有读写权限 | 文件存在,则将其覆盖,否则创建新文件 |
wb+ | 以二进制格式打开文件,并且采用读写模式,一般用于非文本文件,如图片、声音等 | 文件存在,则将其覆盖,否则创建新文件 |
a | 以追加模式打开一个文件,如果改文件已经存在,文件指针将放在文件的末尾(即新内容会被写入已有内容之后),否则,创建新文件用于写入 | 暂无 |
ab | 以二进制格式打开文件,并且采用追加模式,如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于写入 | 暂无 |
a+ | 以读写模式打开文件,如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入已有内容之后),否则,创建新文件用于读写 | 暂无 |
ab+ | 以二进制格式打开文件,并且采用追加模式,如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于读写 | 暂无 |
buffering:可选参数,用于指定读写文件的缓冲模式,值为 0 表示不缓存,值为 1 表示缓存,如果大于 1 则表示缓冲区的大小,默认为缓存模式;
示例:
file1 = open('message.txt', 'w') # 使用 w、w+、a、a+ 方式打开文件,如果文件不存在则创建文件
file2 = open('picture.png', 'rb') # 以二进制格式打开非文本文件
file3 = open('notice.txt', 'r', encoding='utf-8') # 指定编码格式打开文件
open() 函数默认 GBK 编码,也可以指定其他编码,如 ‘utf-8’
- 关闭文件
打开文件后,需要及时关闭,以免对文件造成不必要的破坏。关闭文件可以使用文件对象 的 close() 方法实现。close() 方法会先刷新缓冲区中还没有写入的信息,然后再关闭文件,这样可以将没有写入文件的内容写入文件中。在关闭文件后,便不能再写入了。
为了避免忘记关闭文件,或者打开文件异常导致文件不能被及时关闭,可以使用 Python 提供的 with 语句,从而实现在处理文件时,无论是否抛出异常,都能保证 with 语句执行完毕后关闭已经打开的文件。with 语句的基本语法格式如下:
with expression as target:
with-body
expression:用于指定一个表达式,这里可以是打开文件的 open() 函数;
target:用于指定一个变量,并且将 expression 的结果保存到该变量中;
with-body:用于指定 with 语句体,其中可以是执行 with 语句后相关的一些操作语句,如果不想执行任何语句,可以直接使用 pass 语句代替;
示例:
with open('message.txt', 'w') as file:
pass
- 写入文件
Python 的文件对象提供了 write() 方法,可以向文件中写入内容,在写入文件后,一定要调用 close() 方法关闭文件,否则写入的内容不会保存到文件中,这是因为当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 方法时,操作系统才会保证把没有写入的数据全部写入磁盘。
示例:
file = open('message.txt', 'a')
file.write("hello world !\n")
file.write("hello Python !")
file.close()
在向文件中写入内容后,如果不想马上关闭文件,也可以调用文件对象提供的 flush(0 方法,把缓冲区的内容写入文件,这样也能保证数据全部写入磁盘。
- 读取文件
Python 中的文件对象提供了 read() 方法来读取指定个数的字符,其语法格式如下:
file.read([size])
其中,size 为可选参数,用于指定要读取的字符个数,如果省略则一次性读取所有内容;
使用 read() 方法读取文件时,是从文件的开头读取的。如果想要读取部分内容,可以先试用文件对象的 seek() 方法将文件的指针移动到新的位置,然后再调用 read() 方法读取,seek() 方法的语法格式如下:
file.seek(offset[,whence])
file:表示已经打开的文件对象;
offset:用于指定移动的字符个数,其具体位置与 whence 有关;
whence:用于指定从什么位置开始计算。值为 0 表示从文件头开始计算,1 表示从当前位置开始计算,2 表示从文件尾开始计算,默认为 0;
示例:
if __name__ == '__main__':
with open('message.txt', 'r', encoding='utf-8') as file:
str1 = file.read(32)
print(str1)
str2 = file.read(60)
print(str2)
file.seek(3)
str3 = file.read(3)
print(str3)
上述例子的运行结果为:
问世间,情为何物,直教生死相许?
天南地北双飞客,老翅几回寒暑。
欢乐趣,离别苦,就中更有痴儿女。
君应有语,渺万里层云,千山暮雪,只影向谁去?
横汾路,寂寞当年箫鼓,荒烟依旧平楚。
世间,
有上述例子可知,read() 方法读取的字符个数,对于中文、英文、字符都视为 1 个字符;而 seek() 方法中 offset 的值是根据编码格式来的,比如上述中使用的是 ‘utf-8’ 编码,那么一个中文就占 3 个字符,如果设置 seek(1) 或者 seek(2) 再调用 read() 方法程序就会异常报错;
在使用 read() 方法读取文件时,如果文件很大,一次读取全部内容到内存,容易造成内存不足,所以我们通常会采用逐行读取,也可以读取全部行。读取全部行的作用与调用 read() 方法时不指定 size 类似,只不过读取全部行时,返回的是一个字符串列表,每个元素为文件的一行内容。
示例:
if __name__ == '__main__':
with open('message.txt', 'r', encoding='utf-8') as file:
number = 0
while True:
number += 1
line = file.readline()
if line == "":
break
print(number, line, end='')
print('\n')
file.seek(0)
message = file.readlines()
print(message)
print()
for line in message:
print(line, end='')
上述例子的运行结果为:
1 问世间,情为何物,直教生死相许?
2 天南地北双飞客,老翅几回寒暑。
3 欢乐趣,离别苦,就中更有痴儿女。
4 君应有语,渺万里层云,千山暮雪,只影向谁去?
5 横汾路,寂寞当年箫鼓,荒烟依旧平楚。
6 招魂楚些何嗟及,山鬼暗啼风雨。
7 天也妒,未信与,莺儿燕子俱黄土。
8 千秋万古,为留待骚人,狂歌痛饮,来访雁丘处。
['问世间,情为何物,直教生死相许?\n', '天南地北双飞客,老翅几回寒暑。\n', '欢乐趣,离别苦,就中更有痴儿女。\n', '君应有语,渺万里层云,千山暮雪,只影向谁去?\n', '横汾路,寂寞当年箫鼓,荒烟依旧平楚。\n', '招魂楚些何嗟及,山鬼暗啼风雨。\n', '天也妒,未信与,莺儿燕子俱黄土。\n', '千秋万古,为留待骚人,狂歌痛饮,来访雁丘处。']
问世间,情为何物,直教生死相许?
天南地北双飞客,老翅几回寒暑。
欢乐趣,离别苦,就中更有痴儿女。
君应有语,渺万里层云,千山暮雪,只影向谁去?
横汾路,寂寞当年箫鼓,荒烟依旧平楚。
招魂楚些何嗟及,山鬼暗啼风雨。
天也妒,未信与,莺儿燕子俱黄土。
千秋万古,为留待骚人,狂歌痛饮,来访雁丘处。
目录操作
目录也称文件夹,用于分层保存文件。在 Python 中,内置了 os 模块及其子模块 os.path 用于对目录或文件进行操作。导入该模块后,可以使用该模块提供的通用变量获取与系统相关的信息,常用的变量有以下几个:
- name:用于获取操作系统类型;
- linesep:用于获取当前操作系统上的换行符;
- sep:用于获取当前操作系统所使用的的路径分隔符;
os 模块提供的常用目录操作函数如下表所示:
函数 | 说明 |
---|---|
getcwd() | 返回当前的工作目录 |
listdir(path) | 返回指定路径下的文件和目录信息 |
mkdir(path [,mode]) | 创建目录 |
makedirs(path1/path2…[,mode]) | 创建多级目录 |
rmdir(path) | 删除目录(空目录) |
removedirs(path1/path2…) | 删除多级目录 |
chdir(path) | 把 path 设置为当前工作目录 |
walk(top[,topdown[,onerror]]) | 遍历目录树,该方法返回一个元组,包括所有路径名、所有目录列表和文件列表 3 个元素 |
abspath(path) | 用于获取文件或目录的绝对路径 |
exists(path) | 用于判断目录或者文件是否存在,如果存在返回 True,否则返回 False |
join(path, name) | 将目录与目录或者文件名拼接起来 |
splitext() | 分离文件名和扩展名 |
basename(path) | 从一个目录中提取文件名 |
dirname(path) | 从一个路径中提取文件路径,不包括文件名 |
isdir(path) | 用于判断是否为有效路径 |
高级文件操作
Python 内置的 os 模块除了可以对目录进行操作,还可以对文件进行一些高级操作,如下表所示:
函数 | 说明 |
---|---|
access(path, accessmode) | 获取对文件是否有指定的访问权限(读取/写入/执行权限)。accessmode 的值是 R_OK(读取)、W_OK(写入)、X_OK(执行)或F_OK(存在)。如果有指定的权限,则返回 1,否则返回 0 |
chmod(path, mode) | 修改 path 指定文件的访问权限 |
remove(path) | 删除 path 指定的文件路径 |
rename(src, dst) | 将文件或目录 src 重命名为 dst |
stat(path) | 返回 path 指定文件的信息 |
startfile(path [, operation]) | 使用关联的应用程序打开 path 指定的文件 |
在计算机上创建文件后,该文件本身就会包含一些信息。例如,文件的最后一次访问时间、最后一次修改时间、文件大小等基本信息。通过 os 模块的 stat() 函数可以获取到文件的这些基本信息,stat() 函数返回的对象的常用属性如下表所示:
属性 | 说明 |
---|---|
st_mode | 保护模式 |
st_ino | 索引号 |
st_nlink | 硬链接号(被连接数目) |
st_size | 文件大小,单位为字节 |
st_dev | 设备名 |
st_uid | 用户 ID |
st_gid | 组 ID |
st_atime | 最后一次访问时间 |
st_mtime | 最后一次修改时间 |
st_ctime | 最后一次状态变化时间(系统不同返回结果也不同,例如,在 Windows 操作系统下返回的是文件的创建时间) |
示例:
import os
def formatTime(longTime):
'''
功能:格式化日期时间
:param longTime: 要格式化的时间
:return: 格式化之后的时间
'''
import time
return time.strftime("%Y-%M-%D %H:%M:%S", time.localtime(longTime))
def formatByte(number):
'''
功能:格式化文件大小
:param number: 要格式化的字节数
:return: 格式化之后的文件
'''
for (scale, label) in [(1024*1024*1024,"GB"), (1024*1024,"MB"), (1024,"KB")]:
if number > scale: # 文件大于等于 1KB
return "%.2f %s" % (number*1.0/scale, label)
elif number == 1: # 文件等于 1KB
return "1 字节"
else: # 文件小于 1KB
byte = "%.2f" % (number or 0)
# 去掉结尾的.00,并且加上单位“字节”
return (byte[:-3] if byte.endswith('.00') else byte) + " 字节"
if __name__ == '__main__':
fileInfo = os.stat("picture.png") # 获取文件的基本信息
print("文件的完整路径为:", os.path.abspath("picture.png")) # 获取文件的完整路径
print("索引号:", fileInfo.st_ino)
print("设备名:", fileInfo.st_dev)
print("文件大小:", formatByte(fileInfo.st_size))
print("最后一次修改时间:", formatTime(fileInfo.st_atime))
print("最后一次访问时间:", formatTime(fileInfo.st_mtime))
print("最后一次状态变化时间:", formatTime(fileInfo.st_ctime))
上述例子的运行结果为:
文件的完整路径为: D:\Python\Demo\picture.png
索引号: 2533274790494109
设备名: 3162376725
文件大小: 44.04 KB
最后一次修改时间: 2020-09-08/25/20 20:09:34
最后一次访问时间: 2020-08-08/25/20 20:08:45
最后一次状态变化时间: 2020-09-08/25/20 20:09:34