os模块提供了python操作文件和目录的方法,一些方法不是这么好理解,下面是部分难以理解方法的详解(仅列举Windows平台下的方法):
unix平台可参考:
菜鸟教程:Python3 OS 文件/目录方法
官方文档:官方文档
Windows其他方法也可查看上述以及:
MSDN:MSDN
os.open(file, flags[, mode])
:
flags – 该参数可以是以下选项,多个使用 “|” 隔开:
- os.O_RDONLY: 以只读的方式打开
- os.O_WRONLY: 以只写的方式打开
- os.O_RDWR : 以读写的方式打开
- os.O_APPEND: 以追加的方式打开
- os.O_CREAT: 创建并打开一个新文件
- os.O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)
打开文件并将其截断为零长度; 该文件必须具有写入权限。 无法使用_O_RDONLY指定。 _O_TRUNC与_O_CREAT一起使用可打开现有文件或创建文件。 注意:_O_TRUNC标志会破坏指定文件的内容。
- os.O_EXCL: 如果指定的文件存在,返回错误
如果指定的文件存在,则返回错误,只能和_O_CREAT一起使用
还有一些扩展常量需要由C语言库定义,如果不定义则不存在,不在此列举
dup(fd)
和dup2(fd,fd2)
文件描述符具有“可继承”标志,该标志指示子进程是否可以继承文件描述符。 从Python 3.4开始,Python创建的文件描述符默认是不可继承的。
在UNIX上,在执行新程序时子进程中关闭不可继承的文件描述符,继承其他文件描述符。
在Windows上,不可继承的句柄和文件描述符在子进程中关闭,标准流(文件描述符0,1和2:stdin,stdout和stderr)除外,它们总是被继承。 使用spawn *函数,继承所有可继承的句柄和所有可继承的文件描述符。 使用子进程模块,将关闭除标准流之外的所有文件描述符,并且只有在close_fds参数为False时才继承可继承句柄。
os.dup(fd)
返回一个文件描述符 fd 的副本。该文件描述符的副本是 不可继承的。
在 Windows 中,当复制一个标准流(0: stdin, 1: stdout, 2: stderr)时,新的文件描述符是 可继承的。
在 3.4 版更改: 新的文件描述符现在是不可继承的。
import os,sys
fd=os.open('G://test.txt',os.O_CREAT|os.O_RDWR)
fd2=os.dup(fd)
os.write(fd2,'这是dup2添加进来的'.encode())
结果:
os.dup2(fd,fd2)
把文件描述符 fd 复制为 fd2,必要时先关闭后者。返回 fd2。新的文件描述符默认是 可继承的,除非在 inheritable 为 False 时,是不可继承的。
在 3.4 版更改: 添加可选参数 inheritable。
在 3.7 版更改: 成功时返回 fd2,以过去的版本中,总是返回 None。
import os,sys
fd=os.open('G://test.txt',os.O_CREAT|os.O_RDWR)
#1为stdout标准输出流
os.dup2(fd,1)
os.close(fd)
print("文件关闭成功")
结果:
os.link(src,dst)
硬链接和软连接知识
硬链接就是同一个文件使用了多个别名,由于硬链接是有着相同符号仅文件名不同的文件,因此,删除一个硬链接文件并不影响其他有相同 符号的文件。硬链接对于创建一个已存在文件的拷贝是非常有用的。
硬链接不能对目录进行创建,只可对文件创建。
软链接(也叫符号链接)与硬链接不同,文件用户数据块中存放的内容是另一文件的路径名的指向。软链接就是一个普通文件,只是数据块内容有点特殊。删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接就变成了死链接。
import os, sys
src= "G://test.txt"
dst="G://test2.txt"
# 打开文件
fd = os.open(src, os.O_RDWR|os.O_CREAT )
# 创建硬链接 拷贝src到dst
os.link(src,dst)
#windows建立软连接使用os.symlink(src,dst)需要有权限
# 关闭文件
os.close( fd)
运行前目录存在一个test.txt
执行后多了一个test2.txt,内容如下
os.lseek(fd,pos,how)
通过pos和how设置文件描述符的fd的位置,how:设置SEEK_SET或者0相对位置在文件开始,SEEK_CUR或者1设置相对位置为当前,SEEK_END或者2设置相对位置为文件结尾,返回当前位置相对于开始的光标位置。
import os, sys
# 打开文件
fd = os.open( "G://test.txt", os.O_RDWR|os.O_CREAT )
# 写入字符串
os.write(fd, "This is test".encode())
# 从开始位置读取字符串
pos=os.lseek(fd, 3, 0)
str = os.read(fd, 100)
print(pos)
print ("Read String is : ", str)
# 关闭文件
os.close( fd )
#3
#Read String is : b's is test' 从开始偏离了3个位置
os.stat(path, *, dir_fd=None, follow_symlinks=True)
|os.lstat(path)
|os.fstat(fd)
-
os.stat(path, *, dir_fd=None, follow_symlinks=True)
获取一个文件或者文件描述符的状态,参数可以是一个文件描述符或者文件路径
3.3新版功能:可以添加符号连接或者文件描述符作为参数代替path -
os.fstat(fd)
返回文件描述符状态
-
os.lstat(path)
返回path所指文件状态
返回结构如下:
- st_dev: 设备信息
- st_ino: 文件的i-node值
- st_mode: 文件信息的掩码,包含了文件的权限信息,文件的类型信息(是普通文件还是管道文件,或者是其他的文件类型)
- st_nlink: 硬连接数
- st_uid: 用户ID
- st_gid: 用户组 ID
- st_rdev: 设备 ID (如果指定文件)
- st_size: 文件大小,以byte为单位
- st_blksize: 系统 I/O 块大小
- st_blocks: 文件的是由多少个 512 byte 的块构成的
- st_atime: 文件最近的访问时间
- st_mtime: 文件最近的修改时间
- st_ctime: 文件状态信息的修改时间(不是文件内容的修改时间)
os.makedirs(name, mode=0o777, exist_ok=False)
|os.mkdir(path, mode=0o777, *, dir_fd=None)
-
os.mkdir(path, mode=0o777, *, dir_fd=None)
创建名字为path的目录,如果使用0o777模式,一些系统中该模式可以忽略,如果目录已经存在,则会抛出错误
-
os.makedirs(name, mode=0o777, exist_ok=False)
递归创建目录,像
os.mkdir(path)
一样,但是所有的中间文件夹需要包含子文件夹当前目录下不存在G://python1/test这个路径
使用
os.mkdir(path)
创建,报错:FileNotFoundError: [WinError 3] 系统找不到指定的路径。: ‘G://python1/test’
因为不存在python1这个目录,所以找不到,使用
os.makedirs(name, mode=0o777, exist_ok=False)
进行递归创建即可import os os.makedirs("G://python1/test") print("文件创建成功") #文件创建成功
os.remove(path)
|os.removedirs(path)
|os.rmdir(path)
-
os.remove(path)
删除文件,如果为目录会抛出错误
-
os.removedirs(path)|os.rmdir(path)
分别为递归删除目录和删除目录,如果文件夹不为空会返回错误,现有如下目录G://test/test
使用os.rmdir(path)
import os os.rmdir("G://test/test") print("目录删除成功") #目录删除成功
文件目录为剩下G://test
使用os.removedirs(path)
递归删除目录,G盘不存在*/test/tes*t这个目录os.removedirs(path)方法如果子文件夹删除成功时,才会尝试删除父文件夹,知道抛出一个错误(子文件夹不为空)
os.walk(top, topdown=True, onerror=None, followlinks=False)
通过在目录树中自上而下或者自下而上游走生成文件名。在top中遍历目录,包括他自己,生成一个三元的元祖 (dirpath,dirnames,filenames)
如果设置topdwn=True
或者没有设置,那么将会自上而下生成,相反设置topdown=False
则会自下而上生成
当topdown=True
时,调用者可以就地修改dirnames列表(可能使用del或slice赋值),而walk()
只会递归到名称保留在dirnames中的子目录中; 这可用于修剪搜索,强制执行特定的访问顺序,甚至可以告诉walk()
有关调用者在再次恢复walk()
之前创建或重命名的目录。 当topdown=False
时修改dirnames对walk的行为没有影响,因为在自下而上模式中,dirnames中的目录是在生成dirpath本身之前生成的。
topdown=False
import os
for i,j,k in os.walk(".",topdown=False):
del j[0:1]
print("路径名:{}文件夹名:{}文件名:{}".format(repr(i).ljust(20),repr(j).ljust(20),repr(k).ljust(20)))
#路径名:'.\\.idea\\dictionaries'文件夹名:[] 文件名:['.xml']
#路径名:'.\\.idea' 文件夹名:[] 文件名:['misc.xml', 'modules.xml', 'python程序.iml', 'workspace.xml']
#路径名:'.\\__pycache__' 文件夹名:[] 文件名:['fibo.cpython-36.pyc']
#路径名:'.' 文件夹名:['__pycache__'] 文件名:['fibo.py', 'hello.py']
topdown=True
import os
for i,j,k in os.walk(".",topdown=True):
del j[0:1]
print("路径名:{}文件夹名:{}文件名:{}".format(repr(i).ljust(20),repr(j).ljust(20),repr(k).ljust(20)))
#路径名:'.' 文件夹名:['__pycache__'] 文件名:['fibo.py', 'hello.py']
#路径名:'.\\__pycache__' 文件夹名:[] 文件名:['fibo.cpython-36.pyc']
followlinks
– 设置为 true,则通过软链接访问目录
onerror
–一一般的,发生错误调用scandir()
是忽视的,如果指定onerror
参数,应该是一个函数,它将调用一个参数,一个OSError的实例,他会报错并继续walk,或者提出异常中止walk
os.path
常用方法
方法 | 描述 |
---|---|
os.path.basename(path) | 返回文件名 |
os.path.dirname(path) | 返回目录的路径 |
os.path.split(path) | 分割路径 |
os.path.join(path1,path2,path3) | 将path1、path2、path3合成一个路径可以写多个 |
os.path.getatime(filepath) | 输出文件路径最近访问时间 |
os.path.getctime(filepath) | 输出文件创建时间 |
os.path.getmtime(filepath) | 输出文件最近修改时间 |
os.path.getsize(filepath) | 输出文件大小 |
os.path.abspath(filepath) | 输出绝对路径 |
os.path.normpath(filepath) | 规范filepath字符串形式 |