零、前言
为了长期保存数据以便重复使用、修改和共享,必须将数据以文件的形式存储到外部介质(如磁盘、U盘、光盘等)或云盘中。
按文件中数据的组织形式可以把文件分为2种:
- 文本文件
- 二进制文件
1. 文本文件
文本文件存储的是常规字符串,由若干文本行组成,通常每行以换行符 "\n"结尾。
常规字符串是指记事本或其他文本编辑器能正常显示、编辑并且人类能够直接阅读和理解的字符串,如英文字母、汉字、数字字符串。
文本文件可以使用字处理软件,如gedit、记事本等进行编辑。
2. 二进制文件
二进制文件把对象内容以字节串(bytes)进行存储, 无法用记事本或其他普通文本处理软件直接进行编辑,通常也无法被人类直接阅读和理解,需要使用专门的软件进行解码后读取、显示、修改或执行。
常见的二进制文件:
- 图形图像文件
- 音视频文件
- 可执行文件
- 资源文件
- 数据库文件
- 各类Office文档
3. 文件操作流程
无论是文本文件还是二进制文件,其操作流程基本都是一致的。
- 首先打开文件并创建对象
- 通过该文件对象对文件内容进行读取、写入、删除、修改等操作
- 关闭并保存文件内容
一、文件对象
python内置了文件对象,通过open()函数即可指定模式打开指定文件并创建文件对象。
文件对象名 = open(文件名[, 打开方式[, 缓冲区]])
1. 参数说明
-
文件名
指定了被打开的文件名称,如果要打开的文件不在当前目录,还需要指定完整路径,为了减少完整路径""(如果不使用原始字符串则每一个""要被替换成"\",如"//Users//yuanjun//downloads")的输入,可以使用原始字符串(如r"/Users/yuanjun/downloads")。 -
打开模式
指定了打开文件后的处理方式,例如“只读”、“读写”、“追加”等。
模式 | 说明 |
---|---|
r | 读模式 |
w | 写模式 |
a | 追加模式 |
b | 二进制模式(可与其他模式组合使用) |
+ | 读、写模式(可与其他模式组成使用) |
-
缓冲区
指定了读写文件的缓存模式
模式 | 说明 |
---|---|
0 | 不缓存 |
1 | 缓存,默认 |
>1 | 缓冲区的大小 |
如果执行正常,open()函数返回1个文件对象,通过该文件对象可以对文件进行各种操作。
下面了解一下文件对象的属性和文件对象的常用方法。
2. 文件对象的属性
属性 | 说明 |
---|---|
closed | 判断文件是否关闭,若文件被关闭,则返回True |
mode | 返回文件的打开模式 |
name | 返回文件的名称 |
3. 文件对象常用方法
方法 | 功能说明 |
---|---|
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区的内容写入文件,同时关闭文件,并释放文件对象 |
read([size]) | 从文件中读取 size 个字节(Python2.x) 或 字符(Python3.x) 的内容作为结果返回,如果生了size,则表示一次性读取所有内容 |
readline() | 从文本文件中读取一行内容作为结果返回 |
readlines() | 把文件文件中的每行文本作为一个字符串存入列表中返回该列表 |
seek(offset[, whence]) | 把文件指针移动到新的位置,offset表示相对于whence的位置。whence为0表示从文件头开始计算,1表示从当前位置开始计算,2表示从文件尾开始计算,默认为0 |
tell() | 返回文件指针的当前位置 |
truncate([size]) | 删除从当前指针位置到文件末尾的内容。如果指定了size,则不论指针在什么位置都只留下前size个字节,其余的都删除 |
write(s) | 把字符串s的内容写入文件 |
writelines(s) | 把字符列表写入文本文件,不添加换行符 |
二、二进制文件操作
二进制文件不能使用记事本或其他文件编辑软件正常读写,也无法通过python的文件对象直接读取和理解二进制文件的内容。
必须正确理解二进制文件结构和序列化规则,才能准确地理解其中内容并设计正确的反序列化规则。
序列化:
把内存中的数据在不丢失其类型信息的情况下转成对象的二进制的过程,对象序列化后的形式经过正确的反序列化过程应该能够准确无误地恢复为原来的对象。
python中常用的序列化模块有:
- struct
- pickle
- json
- marshal
- shelve
1. 使用pickle模块
pickle提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,
pickle模块的方法
- pickle.dump(obj, file[, protocol])
序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。
- pickle.load(file)
反序列化对象。将文件中的数据解析为一个Python对象。
注意: 在load(file)的时候,要让python能够找到类的定义,否则会报错。
- pickle.dumps(obj)
将数据通过特殊的形式转换为只有python语言认识的字符串
- pickle.loads(bytes)
将pickle数据转换为python的数据结构
2. 使用struct模块
struct是python(包括版本2和3)中的内建模块,它用来在c语言中的结构体与python中的字符串之间进行转换,数据一般来自文件或者网络。
struct模块中的函数
函数 | return | explain |
---|---|---|
pack(fmt,v1,v2…) | string | 按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回. |
pack_into(fmt,buffer,offset,v1,v2…) | None | 按照给定的格式(fmt),将数据转换成字符串(字节流),并将字节流写入以offset开始的buffer中.(buffer为可写的缓冲区,可用array模块) |
unpack(fmt,v1,v2…..) | tuple | 按照给定的格式(fmt)解析字节流,并返回解析结果 |
pack_from(fmt,buffer,offset) | tuple | 按照给定的格式(fmt)解析以offset开始的缓冲区,并返回解析结果 |
calcsize(fmt) | size of fmt | 计算给定的格式(fmt)占用多少字节的内存,注意对齐方式 |
- struct.pack(fmt,v1,v2,…)
返回的是一个字符串,是参数按照fmt数据格式组合而成。
- struct.unpack(fmt,string)
按照给定数据格式解开(通常都是由struct.pack进行打包)数据,返回值是一个tuple
三、文件级操作
对文件操作的需求 | 方法 |
---|---|
仅需要对文件内容进行读写 | 使用文件对象和序列化方法 |
处理文件路径 | os.path模块 |
使用命令行读取文件内容 | fileinput模块 |
创建临时文件和文件夹 | tempfile模块 |
表示和处理文件系统路径的类 | pathlib模块 |
1. os与os.path模块
os模块除了提供使用操作系统功能和访问文件系统的简便方法之外,还提供了大量文件级操作的方法,os模块提供了大量用于路径判断、切分、连接以及文件夹遍历的方法。
如下表所示
方法 | 功能说明 |
---|---|
access(path, mode) | 按照 mode 指定的权限访问文件 |
open(path, flags, mode=0o777, *, dir_fd=None) | 按照 mode 指定的权限打开文件,默认权限为可读、可写、可执行 |
chmod(path, mode, *, dir_fd=None, follow_symlinks=True | 改变文件的访问权限 |
remove(path) | 删除指定的文件 |
removedirs(path) | 递归删除目录,只能删除目录下没有内容的文件夹,否则报错OSError: [Errno 66] Directory not empty: |
rename(src, dst) | 重命名文件或目录 |
stat(path) | 返回文件的所有属性 |
fstst(path) | 返回打开的文件的所有属性 |
listdir(path) | 返回path目录下的文件和目录列表 |
startfile(filepath[, operation]) | 使用关联的应用程序打开指定文件 |
abspath(path) | 返回绝对路径 |
dirname(p) | 返回目录的路径 |
exists(path) | 判断文件是否存在 |
getatime(filename) | 返回文件的最后访问时间 |
getctime(filename) | 返回文件的创建时间 |
getmtime(filename) | 返回文件的最后修改时间 |
getsize(filename) | 返回文件的大小 |
isabs(path) | 判断path是否为绝对路径 |
isdir(path) | 判断path是否为目录 |
isfile(path) | 判断path是否为文件 |
join(path, * paths) | 连接两个或多个path |
split(path) | 对路径进行分割,以元组形式返回 |
splitext(path) | 从路径中分割文件的扩展名 |
splitdrive(path) | 从路径中分割驱动器的名称 |
2. shutil模块
shutil模块也提供了大量的方法支持文件和文件夹操作,举例一些常用方法如下表:
方法 | 功能说明 |
---|---|
shutil.copy(src,dest) | 将目标文件拷贝到目标路径,目标路径必须存在。如果源文件已经存在目标路径,直接覆盖。 拷贝到目标路径后,文件的状态(连接时间和更新时间)都会被更新,文件名、文件内容和文件的权限都不变。 |
shutil.copyfile(src,dest) | 拷贝文件,src和dest是带文件名的路径,如/Users/Documents/test.txt'源文件必须存在,拷贝的文件内容不变,可以改变目标文件名,xyz.txt是test.txt的复制,内容一样,名字改了 |
shutil.move(src,dest) | 递归地将文件或目录(src)移动到另一个位置(dst)。目标目录应该不存在。如果目标是一个目录或指向一个目录的符号链接,那么src将被移动到该目录中。 |
shutil.copytree(src , dest) | 递归地将src下的整个目录树复制到dest。src必须存在,dest必须不存在。 |
shutil.rmtree(path) | 递归地删除目录和目录下的所有内容 |
四、目录操作
除了支持文件操作,os和os.path模块还提供了大量的目录操作方法,os模块常用目录操作方法与成员表如下图所示:
方法 | 功能说明 |
---|---|
mkdir(path[, mode=0777] | 创建目录 |
makedirs(path1/path2..., mode=511) | 创建多级目录 |
rmdir(path) | 删除目录 |
removedirs(path1/path2...) | 删除多级目录 |
listdir(path) | 返回指定目录下的文件和目录信息 |
getcwd() | 返回当前工作目录 |
get_exec_path() | 返回可执行文件的搜索路径 |
chdir(path) | 将path设为当前工作目录 |
walk(top, topdown=True, onerror=None) | 遍历目录树,该方法返回一个元组,包括3个元素: 所有路径名、所有目录列表与文件列表 |
sep | 当前操作系统所使用的路径分隔符 |
extsep | 当前操作系统所使用的文件扩展名分隔符 |
网友评论