Python 文件及目录操作

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

基本文件操作

  1. 打开文件

在 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’

  1. 关闭文件

打开文件后,需要及时关闭,以免对文件造成不必要的破坏。关闭文件可以使用文件对象 的 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
  1. 写入文件

Python 的文件对象提供了 write() 方法,可以向文件中写入内容,在写入文件后,一定要调用 close() 方法关闭文件,否则写入的内容不会保存到文件中,这是因为当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 方法时,操作系统才会保证把没有写入的数据全部写入磁盘

示例:

扫描二维码关注公众号,回复: 11599763 查看本文章
file = open('message.txt', 'a')
file.write("hello world !\n")
file.write("hello Python !")
file.close()

在这里插入图片描述

在向文件中写入内容后,如果不想马上关闭文件,也可以调用文件对象提供的 flush(0 方法,把缓冲区的内容写入文件,这样也能保证数据全部写入磁盘。

  1. 读取文件

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

更多请参考

猜你喜欢

转载自blog.csdn.net/qq_34139994/article/details/108185518