读写文件是程序经常需要做的事情,Python内置函数提供了简单的读写文件方式,os模块、io模块提供了一些较复杂的对象。
本章重点学习一下内置函数操作文件,对其他内置模块的文件操作对象会简要的介绍,如果需要使用复杂的文件对象,可以查看相关的对象说明。
文件的相关概念
文件、目录和路径是计算机中非常重要的概念,我们这里只做简单的介绍,如果需要详细了解,可以查阅相关的文档。
文本文件和二进制文件
在计算机中,把存储数据的单元成为文件。文件中的数据可以是文本数据,例如源代码,没有任何格式的数据,有格式的xml数据等等;数据也可以是“二进制”数据,这种数据人很难识别,要靠编程后由计算机来读取(或写入),如视频数据、图片数据、数据流等等,这些数据人看到的只是一些0和1的二进制数据流,不借助于计算机,很难看出来这些数据是什么内容,因此被称呼为“二进制”数据。有些二进制数据是有结构的,也就是它的数据内容的位置是固定的,有一些数据是没有结构的,它完全是流式的,需要通过一些特殊的标记来识别当前数据流表示的含义。
目录和路径
计算机里有很多很多文件,比如你现在正在使用的计算机,一般为windows或者mac,上面有几十万,甚至几百万个文件。这么多文件需要有一套方法去管理,计算机一般采用树形结构进行管理。树形结构里每个树枝下面可以有多个文件和多个子树枝,树叶就是文件,树枝在计算机里被称为“目录”,树干在计算机里称呼为“根目录”。mac和linux等系统都只有一个根目录,windows系统没有根目录的概念,它有一个特殊的概念“盘符”,例如c:,d:,与根目录的概念接近。
文件的目录下面可以是子目录,文件的目录可以嵌套,多个嵌套的目录通过斜杠分割开来,可以写成如下的形式:
/User/my/PycharmProjects/pythonProject/main.py
前面的/User/my/PycharmProjects/pythonProject/都是目录,只有main.py是文件。
通常把/User/my/PycharmProjects/pythonProject/称呼为存放main.py的路径,只有通过“路径”我们才能找到这个文件。
上面的路径中,第一个斜杠就是根路径,这种带根路径的路径称呼为绝对路径
如果我们的工作路径是/User/my,那PycharmProjects/pythonProject/就是相对路径,相对路径是相对于某个路径(通常就是工作路径)而言的。
在计算机中,使用.表示当前的工作路径,所以上面的相对路径也可以写成./PycharmProjects/pythonProject/
当前路径的上一级目录,称呼为父目录,使用…来表示,…/my/PycharmProjects/pythonProject/与上面的路径是相同的。
在描述一个文件的时候,可以只给文件名,也可以文件名和路径名一起给出(称呼为带路径的文件),在编程时,通常都是要带上文件的路径,或绝对路径,或相对路径,因为编程的时候,我们是要程序去使用文件,只有带路径的文件,程序才能方便的去寻找它。
文件的主要操作
文件的主要操作分为创建、读、写和删除。
创建文件就是从无到有的新建一个文件,需要给予文件名字,以及写入一部分内容。
文件读是指从打开一个文件,从里面把内容读出来,一般是把文件里的数据读入到程序变量中。注意,文件中的数据是“静态的”,它自己是不能做出任何动作的,一个文件(如可执行文件)它能做出动作或者指令,是因为读取它的程序,按照文件里的数据进行了相对应的动作。
一般来说,文件都是“顺序”的,就跟我们的“读”文章一样,从开头到结尾,要一个个字的去读。
文件写分为两种情况,一种是覆盖写,一种是追加写。
所谓覆盖写就是只我不管文件里的内容是什么,我就从文件开头开始写,会把以前写的内容“覆盖”掉。你可以理解为纸上已经有一段文章了,我们再文章上面再写一篇文章,与在纸上书写不一样,覆盖写会把原来的内容“擦除”掉,写上新的内容,并不是原有数据和新数据的交叠。
追加写,就是我们直接跳过前面已经写过的内容,从原来内容的结尾处开始,写入新的内容。
删除文件,就是销毁文件,文件被删除后,其内容就被销毁了,需要谨慎进行删除操作。
那有没文件的修改呢?
有啊,就是前面的覆盖写,可以移动要覆盖写的起始位置,覆盖写入新的内容,就是修改了。但要注意,只能修改等量的数据,如果待修改的数据比新数据长,那就会留下一部分待修改数据,如果新数据比待修改数据长,那信数据就会写不全(或者把不需要覆盖写的数据给覆盖了)
另外,现代计算机系统将文件的访问、读、写设置了权限,如果你只有访问权限没有读写权限,只能对看到文件名,不能读写文件内容,如果有读文件权限,可以读出文件内容,但不能写入文件数据。
open()
无论是读或是写一个文件,都需要先打开一个文件,open()函数就是打开文件,并创建一个文件对象返回。
语法为:
open(
file,
mode='r',
buffering=-1,
encoding=None,
errors=None,
newline=None,
closefd=True,
opener=None,
)
参数说明:
- file:file 是带路径的文件
- mode:默认为 ‘r’,指定打开文件的模式,支持的模式见下表。
- buffering:设置缓冲策略
- encoding:是用于解码或编码文件的编码的名称,这只能在文本模式下使用,默认编码依赖于平台,但 Python 支持的任何编码都可以传递。
- errors:指定如何处理编码和解码错误,不能在二进制模式下使用。
- newline:控制如何换行
- closefd:如果 closefd 为 False 且给出的不是文件名而是文件描述符,那么当文件关闭时,底层文件描述符将保持打开状态。如果给出的是文件名,则 closefd 必须为 True (默认值),否则将触发错误。
- opener: 可以通过传递可调用的 opener 来使用自定义开启器。然后通过使用参数( file,flags )调用 opener 获得文件对象的基础文件描述符。 opener 必须返回一个打开的文件描述符(使用 os.open as opener 时与传递 None 的效果相同)。
支持的模式:
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
Python读写文件区分文本文件和二进制文件,读文本文件时,返回内容是字符串,二进制模式返回的类型是bytes对象。
buffering 是用于设置缓冲策略的可选整数。规则有:
缓冲是用于设置缓冲策略的可选整数。规则有:
- 传递 0 以关闭缓冲(仅在二进制模式下允许)
- 传递 1 以选择行缓冲(仅在文本模式下可用)
- 传递大于1的整数以指示固定大小块缓冲区的字节大小
- 如果取负值,寄存区的缓冲大小则为系统默认
如果未给出缓冲参数(使用默认的或者负值),默认缓冲策略的工作方式如下:
- 二进制文件缓冲在固定大小的块中; 缓冲区的大小使用启发式选择,试图确定底层设备的默认缓冲区块大小(block size)和 回溯到
io.DEFAULT_BUFFER_SIZE
和回溯到io。默认缓冲区大小。在许多系统上,缓冲区的长度通常为4096或8192字节。 - “交互式”文本文件( satty() 返回 True的文件)使用行缓冲。其他文本文件使用上述策略用于二进制文件。
errors 是一个可选的字符串参数,用于指定如何处理编码和解码错误 - 这不能在二进制模式下使用。可以使用各种标准错误处理程序(列在 错误处理方案 ),但是使用 codecs.register_error() 注册的任何错误处理名称也是有效的。标准名称包括:
- 如果存在编码错误,‘strict’ 会引发 ValueError 异常。 默认值 None 具有相同的效果。
- ‘ignore’ 忽略错误。请注意,忽略编码错误可能会导致数据丢失。
- ‘replace’ 会将替换标记(例如 ‘?’ )插入有错误数据的地方。
- ‘surrogateescape’ 将把任何不正确的字节表示为
U+DC80
至U+DCFF
范围内的下方替代码位。 当在写入数据时使用 - surrogateescape 错误处理句柄时这些替代码位会被转回到相同的字节。 这适用于处理具有未知编码格式的文件。
- 只有在写入文件时才支持 ‘xmlcharrefreplace’。编码不支持的字符将替换为相应的XML字符引用
&#nnn;
。 - ‘backslashreplace’ 用Python的反向转义序列替换格式错误的数据。
- ‘namereplace’ (也只在编写时支持)用
\N{...}
转义序列替换不支持的字符。
newline 控制 universal newlines 模式如何生效(它仅适用于文本模式)。它可以是 None,'','\n','\r' 和 '\r\n'
。它的工作原理:
- 从流中读取输入时,如果 newline 为 None,则启用通用换行模式。输入中的行可以以 ‘\n’,‘\r’ 或 ‘\r\n’ 结尾,这些行被翻译成 ‘\n’ 在返回呼叫者之前。如果它是 ‘’,则启用通用换行模式,但行结尾将返回给调用者未翻译。如果它具有任何其他合法值,则输入行仅由给定字符串终止,并且行结尾将返回给未调用的调用者。
- 将输出写入流时,如果 newline 为 None,则写入的任何 ‘\n’ 字符都将转换为系统默认行分隔符 os.linesep。如果 newline 是 ‘’ 或 ‘\n’,则不进行翻译。如果 newline 是任何其他合法值,则写入的任何 ‘\n’ 字符将被转换为给定的字符串。
文件对象
一个文件被open()函数打开后,将返回文件对象,可以通过文件对象进行各种操作。
文件对象的属性:
属性 | 描述 |
---|---|
file.closed | 返回true如果文件已被关闭,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称。 |
file.softspace | 如果用print输出后,必须跟一个空格符,则返回false。否则返回true。 |
file = open('test.txt', 'r')
print(f"文件名:{file.name=}”) #文件名:file.name='test.txt'
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
print(f"访问模式:{file.mode=}”) #访问模式:file.mode='r'
print(f"{file.buffer=}”) #file.buffer=<_io.BufferedReader name='test.txt'>
print(f"{file.encoding=}”) #file.encoding='UTF-8'
print(f"{file.errors=}”) #file.errors='strict'
文件对象的常见方法:
方法 | 方法及描述 |
---|---|
file.close() | 关闭文件。关闭后文件不能再进行读写操作。 |
file.flush() | 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 |
file.fileno() | 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 |
file.isatty() | 如果文件连接到一个终端设备返回 True,否则返回 False。 |
file.next() | 返回文件下一行。 |
file.read([size]) | 从文件读取指定的字节数,如果未给定或为负则读取所有。 |
file.readline([size]) | 读取整行,包括 “\n” 字符。 |
file.readlines(sizeint]) | 读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。 |
file.seek(offset[,whence]) | 设置文件当前位置 |
file.tell() | 返回文件当前位置。 |
file.truncate([size]) | 截取文件,截取的字节通过size指定,默认为当前文件位置。 |
file.write(str) | 将字符串写入文件,返回的是写入的字符长度。 |
file.writelines(sequence) | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
for line in file: | |
print(line) | 通过迭代器访问文件内容 |
关闭文件
使用open()函数打开的文件,必须要关闭。
语法为:
file.close()
close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
文件必须被正常关闭,否则可能会引发文件锁或者文件句柄数太多等系统问题。
file = open('test.txt', 'r')
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
file.close()
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=True
为了保证在异常情况下关闭文件,一般要把close()方法写到try…finally里,也可以通过上下文管理器进行自动管理:
with open('test.txt', 'r') as file:
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=False
pass
print(f"是否已关闭:{file.closed=}”) #是否已关闭:file.closed=True
向文件中写入数据
向文件中写入数据有多个方法:
file.write(str)
file.writelines(list)
file.write(str)将字符串str写文件
file.writelines(list)将一个字符串list写入文件,注意默认是没有换行符的,需要自己在行尾增加换行符。
读取文件数据
读取文件数据有多种方法:
file.read([count])
file.readline([size])
file.readlines()
count是要读取的字节数
size是读取一行的最大字节数。
with open('test.txt', 'w') as file:
file.write('I love Python!')
file.writelines(['one\n', 'two\n', 'three'])
with open('test.txt', 'r') as file:
print(file.read(14))
print(file.readline())
print(file.readlines())
‘''
I love Python!
one
['two\n', 'three']
‘''
注意写入文件如果使用w模式,每次都是重头开始覆盖写文件。
由于 readline() 函数在读取文件中一行的内容时,会读取最后的换行符“\n”,再加上 print() 函数输出内容时默认会换行,所以输出结果中会看到多出了一个空行。
也可以通过for…in…的方式读取文件:
with open('test.txt', 'w') as file:
file.write('I love Python!')
file.writelines(['one\n', 'two\n', 'three'])
with open('test.txt', 'r') as file:
for line in file:
print(line)
‘''
I love Python!one
two
three
‘''
文件位置定位
也可以指定位置开始读写。
tell()方法可以告诉我们当前文件的位置,seek(offset [,from])方法改变当前文件的位置。
offset变量表示要移动的字节数。from变量指定开始移动字节的参考位置。
如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。
with open('test.txt', 'w') as file:
file.write('I love Python!')
file.writelines(['one\n', 'two\n', 'three'])
print(file.tell())
file.seek(0, 0)
file.write('I hate Python!')
with open('test.txt', 'r') as file:
print(file.read())
‘''
27
I hate Python!one
two
three
‘''
os模块中的常见文件操作
os 模块提供了非常丰富的函数用来处理文件和目录。
函数 | 描述 |
---|---|
os.access(path,mode) | 检验权限模式 |
os.chdir(path) | 改变当前工作目录 |
os.chflags(path,flags) | 设置路径的标记为数字标记。 |
os.chmod(path,mode) | 更改权限 |
os.chown(path,uid,gid) | 更改文件所有者 |
os.chroot(path) | 改变当前进程的根目录 |
os.close(fd) | 关闭文件描述符 fd |
os.closerange(fd_low,fd_high) | 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
os.dup(fd) | 复制文件描述符 fd |
os.dup2(fd,fd2) | 将一个文件描述符 fd 复制到另一个 fd2 |
os.fchdir(fd) | 通过文件描述符改变当前工作目录 |
os.fchmod(fd,mode) | 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
os.fchown(fd,uid,gid) | 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
os.fdatasync(fd) | 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
os.fdopen(fd[,mode[,bufsize]]) | 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
os.fpathconf(fd,name) | 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
os.fstat(fd) | 返回文件描述符fd的状态,像stat()。 |
os.fstatvfs(fd) | 返回包含文件描述符fd的文件的文件系统的信息,像 statvfs() |
os.fsync(fd) | 强制将文件描述符为fd的文件写入硬盘。 |
os.ftruncate(fd,length) | 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
os.getcwd() | 返回当前工作目录 |
os.getcwdu() | 返回一个当前工作目录的Unicode对象 |
os.getenv() | 读取环境变量 |
os.getlogin() | 返回进程的控制终端上登录的用户的名称。 |
os.putenv() | 设置环境变量 |
os.isatty(fd) | 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
os.lchflags(path,flags) | 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
os.lchmod(path,mode) | 修改连接文件权限 |
os.lchown(path,uid,gid) | 更改文件所有者,类似 chown,但是不追踪链接。 |
os.link(src,dst) | 创建硬链接,名为参数 dst,指向参数 src |
os.listdir(path) | 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
os.lseek(fd,pos,how) | 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
os.lstat(path) | 像stat(),但是没有软链接 |
os.major(device) | 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
os.makedev(major,minor) | 以major和minor设备号组成一个原始设备号 |
os.mkedirs(path[,mode]) | 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
os.minor(device) | 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
os.mkdir(path[,mode]) | 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
os.mkfifo(path[,mode]) | 创建命名管道,mode 为数字,默认为 0666 (八进制) |
os.mknod(filename[,mode=0600,device]) | 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 |
os.open(file,flags[,mode]) | 打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
os.openpty() | 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
os.pathconf(path,name) | 返回相关文件的系统配置信息。 |
os.pipe() | 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
os.popen(command[,mode[,bufsize]]) | 从一个 command 打开一个管道 |
os.read(fd,n) | 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
os.readlink(path) | 返回软链接所指向的文件 |
os.remove(path) | 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
os.removedirs(path) | 递归删除目录。 |
os.rename(src,dst) | 重命名文件或目录,从 src 到 dst |
os.renames(old,new) | 递归地对目录进行更名,也可以对文件进行更名。 |
os.rmdir(path) | 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
os.stat(path) | 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
os.stat_float_times([newvalue]) | 决定stat_result是否以float对象显示时间戳 |
os.statvfs(path) | 获取指定路径的文件系统统计信息 |
os.symlink(src,dst) | 创建一个软链接 |
os.system() | 运行shell命令 |
os.exit() | 终止当前进程 |
os.tcgetgrp(fd) | 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
os.tcsetpgrp(fd,pg) | 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 |
os.tempnam([dir[,prefix]]) | 返回唯一的路径名用于创建临时文件。 |
os.tmpfile() | 返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 |
os.tmpnam() | 为创建一个临时文件返回一个唯一的路径 |
os.ttyname(fd) | 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
os.unlink(path) | 删除文件 |
os.utime(path,times) | 返回指定的path文件的访问和修改的时间。 |
os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]]) | 输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
os.write(fd,str) | 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
os.path | 获取文件的属性信息。 |
子模块os.path的函数:
函数 | 说明 |
---|---|
os.path.abspath(path) | 返回绝对路径 |
os.path.basename(path) | 返回文件名 |
os.path.commonprefix(list) | 返回list(多个路径)中,所有path共有的最长的路径 |
os.path.dirname(path) | 返回文件路径 |
os.path.exists(path) | 如果路径 path 存在,返回 True;如果路径 path 不存在或损坏,返回 False。 |
os.path.lexists(path) | 路径存在则返回 True,路径损坏也返回 True |
os.path.expanduser(path) | 把 path 中包含的 ~ 和 ~user 转换成用户目录 |
os.path.expandvars(path) | 根据环境变量的值替换 path 中包含的 $name 和 ${name} |
os.path.getatime(path) | 返回最近访问时间(浮点型秒数) |
os.path.getmtime(path) | 返回最近文件修改时间 |
os.path.getctime(path) | 返回文件 path 创建时间 |
os.path.getsize(path) | 返回文件大小,如果文件不存在就返回错误 |
os.path.isabs(path) | 判断是否为绝对路径 |
os.path.isfile(path) | 判断路径是否为文件 |
os.path.isdir(path) | 判断路径是否为目录 |
os.path.islink(path) | 判断路径是否为链接 |
os.path.ismount(path) | 判断路径是否为挂载点 |
os.path.join(path1[, path2[, …]]) | 把目录和文件名合成一个路径 |
os.path.normcase(path) | 转换path的大小写和斜杠 |
os.path.normpath(path) | 规范path字符串形式 |
os.path.realpath(path) | 返回path的真实路径 |
os.path.relpath(path[, start]) | 从start开始计算相对路径 |
os.path.samefile(path1, path2) | 判断目录或文件是否相同 |
os.path.sameopenfile(fp1, fp2) | 判断fp1和fp2是否指向同一文件 |
os.path.samestat(stat1, stat2) | 判断stat tuple stat1和stat2是否指向同一个文件 |
os.path.split(path) | 把路径分割成 dirname 和 basename,返回一个元组 |
os.path.splitdrive(path) | 一般用在 windows 下,返回驱动器名和路径组成的元组 |
os.path.splitext(path) | 分割路径,返回路径名和文件扩展名的元组 |
os.path.splitunc(path) | 把路径分割为加载点与文件 |
os.path.walk(path, visit, arg) | 遍历path,进入每个目录都调用visit函数,visit函数必须有3个参数(arg, dirname, names),dirname表示当前目录的目录名,names代表当前目录下的所有文件名,args则为walk的第三个参数 |
os.path.supports_unicode_filenames | 设置是否支持unicode路径名 |
import os
# 获取文件路径
file_path = "/Users/username/Documents/test.txt"
dir_path = os.path.dirname(file_path)
print("文件路径为:", file_path)
print("文件所在目录为:", dir_path)
‘’’
文件路径为: /Users/username/Documents/test.txt
文件所在目录为: /Users/username/Documents
’’’
file_path = "/Users/username/Documents/test.txt"
file_name = os.path.basename(file_path)
print("文件路径为:", file_path)
print("文件名为:", file_name)
‘’’
文件路径为: /Users/username/Documents/test.txt
文件名为: test.txt
’’’
# 获取文件扩展名
file_path = "/Users/username/Documents/test.txt"
file_ext = os.path.splitext(file_path)[1]
print("文件路径为:", file_path)
print("文件扩展名为:", file_ext)
‘’’
文件路径为: /Users/username/Documents/test.txt
文件扩展名为: .txt
’‘’
检测文件或目录是否存os.access()
检查文件或目录是否存在和可访问,语法为:
os.access(path, mode)
参数:
-
path – 要用来检测是否有访问权限的路径。
-
mode – mode为F_OK,测试存在的路径,或者它可以是包含R_OK, W_OK和X_OK或者R_OK, W_OK和X_OK其中之一或者更多。
-
os.F_OK: 作为access()的mode参数,测试path是否存在。
-
os.R_OK: 包含在access()的mode参数中 , 测试path是否可读。
-
os.W_OK 包含在access()的mode参数中 , 测试path是否可写。
-
os.X_OK 包含在access()的mode参数中 ,测试path是否可执行。
如果允许访问返回 True , 否则返回False。
import os
print(os.access('test.txt', os.F_OK))
print(os.access('test.txt', os.W_OK))
os.open()
用于打开一个文件,并且设置需要的打开选项,模式参数mode参数是可选的,默认为 0777。
语法格式如下:
os.open(path, flags, mode=0o777, *, dir_fd=None)
参数:
-
file – 要打开的文件
-
flags – 该参数可以是以下选项,多个使用 “|” 隔开:
-
os.O_RDONLY: 以只读的方式打开
-
os.O_WRONLY: 以只写的方式打开
-
os.O_RDWR : 以读写的方式打开
-
os.O_NONBLOCK: 打开时不阻塞
-
os.O_APPEND: 以追加的方式打开
-
os.O_CREAT: 创建并打开一个新文件
-
os.O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)
-
os.O_EXCL: 如果指定的文件存在,返回错误
-
os.O_SHLOCK: 自动获取共享锁
-
os.O_EXLOCK: 自动获取独立锁
-
os.O_DIRECT: 消除或减少缓存效果
-
os.O_FSYNC : 同步写入
-
os.O_NOFOLLOW: 不追踪软链接
-
mode 可用以下选项按位或操作生成, 目录的读权限表示可以获取目录里文件名列表, ,执行权限表示可以把工作目录切换到此目录 ,删除添加目录里的文件必须同时有写和执行权限 ,文件权限以用户id->组id->其它顺序检验,最先匹配的允许或禁止权限被应用。
-
stat.S_IXOTH: 其他用户有执行权0o001
-
stat.S_IWOTH: 其他用户有写权限0o002
-
stat.S_IROTH: 其他用户有读权限0o004
-
stat.S_IRWXO: 其他用户有全部权限(权限掩码)0o007
-
stat.S_IXGRP: 组用户有执行权限0o010
-
stat.S_IWGRP: 组用户有写权限0o020
-
stat.S_IRGRP: 组用户有读权限0o040
-
stat.S_IRWXG: 组用户有全部权限(权限掩码)0o070
-
stat.S_IXUSR: 拥有者具有执行权限0o100
-
stat.S_IWUSR: 拥有者具有写权限0o200
-
stat.S_IRUSR: 拥有者具有读权限0o400
-
stat.S_IRWXU: 拥有者有全部权限(权限掩码)0o700
-
stat.S_ISVTX: 目录里文件目录只有拥有者才可删除更改0o1000
-
stat.S_ISGID: 执行此文件其进程有效组为文件所在组0o2000
-
stat.S_ISUID: 执行此文件其进程有效用户为文件所有者0o4000
-
stat.S_IREAD: windows下设为只读
-
stat.S_IWRITE: windows下取消只读
-
dir_fd基于目录描述符的相对路径: 如果 dir_fd 不是
None
,它就应该是一个指向目录的文件描述符,这时待操作的 path 应该是相对路径,相对路径是相对于前述目录的。如果 path 是绝对路径,则 dir_fd 将被忽略。
import os, sys
# 打开文件
fd = os.open( "foo.txt", os.O_RDWR|os.O_CREAT )
# 写入字符串
os.write(fd, "This is test")
# 关闭文件
os.close( fd )
os.fdopen()
通过文件描述符 fd 创建一个文件对象,并返回这个文件对象。
法格式如下:
os.fdopen(fd, [, mode[, bufsize]]);
参数:
- fd – 打开的文件的描述符,在Unix下,描述符是一个小整数。
- mode – 可选,和bufsize参数和Python内建的open函数一样,mode参数可以指定『r,w,a,r+,w+,a+,b』等,表示文件的是只读的还是可以读写的,以及打开文件是以二进制还是文本形式打开。这些参数和C语言中的<stdio.h>中fopen函数中指定的mode参数类似。
- bufsize – 可选,指定返回的文件对象是否带缓冲:bufsize=0,表示没有带缓冲;bufsize=1,表示该文件对象是行缓冲的;bufsize=正数,表示使用一个指定大小的缓冲冲,单位为byte,但是这个大小不是精确的;bufsize=负数,表示使用一个系统默认大小的缓冲,对于tty字元设备一般是行缓冲,而对于其他文件则一般是全缓冲。如果这个参数没有制定,则使用系统默认的缓冲设定。
通过文件描述符返回的文件对象。
import os, sys
# 打开文件
fd = os.open( "foo.txt", os.O_RDWR|os.O_CREAT )
# 获取以上文件的对象
fo = os.fdopen(fd, "w+")
# 获取当前文章
print(f"Current I/O pointer position :{fo.tell()}")
# 写入字符串
fo.write( "Python is a great language.\nYeah its great!!\n");
# 读取内容
os.lseek(fd, 0, 0)
str = os.read(fd, 100)
print("Read String is : ", str)
# 获取当前位置
print(f"Current I/O pointer position :{fo.tell()}")
# 关闭文件
os.close( fd )
print("关闭文件")
open()、os.open()、os.fdopen()
open() 函数用于打开一个文件,创建一个文件对象
os.open()创建操作系统级文件描述符
os.fdopen()从文件描述符中创建一个文件对象。也就是说,os.fdopen()是以os.open()返回的基础上得到一个文件对象。
os.close()
关闭指定的文件描述符 。
语法格式如下:
os.close(fd);
该方法没有返回值。
os.read()
用于从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。
在Unix,Windows中有效
语法格式如下:
os.read(fd,n)
参数:
- fd – 文件描述符。
- n – 读取的字节。
返回包含读取字节的字符串
os.write()
语法格式如下:
os.write(fd, str)
参数:
- fd – 文件描述符。
- str – 写入的字符串。
该方法返回写入的实际位数。
os.rename()
rename() 方法需要两个参数,当前的文件名和新文件名。
语法:
os.rename(current_file_name, new_file_name)
例子:
下例将重命名一个已经存在的文件test1.txt。
import os
# 重命名文件test1.txt到test2.txt。
os.rename( "test1.txt", "test2.txt" )
os.remove()
可以用remove()方法删除文件,需要提供要删除的文件名作为参数。
语法:
os.remove(file_name)
例子:
下例将删除一个已经存在的文件test2.txt
import os
# 删除一个已经存在的文件test2.txt
os.remove("test2.txt")
os.mkdir()
语法:
os.mkdir("newdir")
例子:
下例将在当前目录下创建一个新目录test。
import os
# 创建目录test
os.mkdir("test")
os.rmdir()
删除目录,目录名称以参数传递。
在删除这个目录之前,它的所有内容应该先被清除。
语法:
os.rmdir('dirname')
例子:
以下是删除" /tmp/test"目录的例子。目录的完全合规的名称必须被给出,否则会在当前目录下搜索该目录。
import os
删除”/tmp/test”目录
os.rmdir( “/tmp/test” )
以上就是“Python进阶(八)文件操作”的全部内容,希望对你有所帮助。
关于Python技术储备**
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
最后祝大家天天进步!!
上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。
**