Python::OS 模块 -- 文件和目录操作
下面介绍一下os模块中提供的一些文件操作(仅限unix平台):
返回文件对象的操作
os.fdopen(fd, [mode, [bufsize]])
通过文件描述符 fd 创建一个文件对象,并返回这个文件对象
fd参数是一个打开的文件的描述符,在unix下,描述符是一个小整数。
mode参数是可选的,和buffersize参数和python内建的open函数一样,mode参数可以指定‘r,w,a,r+,w+,a+,b’等,表示文件的是只读的还是可以读写的,以及打开文件是以二进制还是文本形式打开。这些参数和c语言中的<stdio.h>中fopen函数中指定的mode参数类似。
bufsize参数是可选的,指定返回的文件对象是否带缓冲:buffersize=0,表示没有带缓冲;bufsize=1,表示该文件对象是行缓冲的;bufsize=正数,表示使用一个指定大小的缓冲冲,单位为byte,但是这个大小不是精确的;bufsize=负数,表示使用一个系统默认大小的缓冲,对于tty字符设备一般是行缓冲,而对于其他文件则一般是全缓冲。如果这个参数没有制定,则使用系统默认的缓冲设定。
os.popen(command, [mode, [bufsize]])
开启一个子进程执行一个command指定的命令,在父进程和子进程之间建立一个管道pipe,用于在父子进程间通信。返回一个文件对象,可以对这个文件对象进行读或写,取决于参数mode,如果mode指定了只读,那么只能对文件对象进行读,如果mode参数指定了只写,那么只能对文件对象进行写操作。
command参数指定需要在子进程中执行的命令.
mode参数和bufsize参数和上述的os.fdopen一样。
os.popen函数还有一些其他的变种,可以按需要使用:
os.popen2(command, [mode, [bufsize]])
在子进程中执行命令command,返回一个二元组(child_stdin, child_stdout)
os.popen3(command, [mode, [bufsize]])
在子进程中执行命令command,返回一个三元组(child_stdin, child_stdout, child_stderr)
os.popen4(command, [mode, [bufsize]])
在子进程中执行命令command,返回一个二元组(child_stdin, child_stdout_and_stderr)
os.tmpfile()
返回一个以”w+b“模式打开的文件对象,该文件对象对应的文件无法通过目录访问,这是一个临时文件,当文件对象被关闭的时候,该临时文件也就被删除。
文件描述符操作
os.close(fd)
以文件描述符fd为参数来关闭fd指向的打开的文件。
os.closerange(fd_low, fd_high)
关闭一些列连续的文件描述符,文件描述符的范围从fd_low到fd_high - 1。
os.dup(fd)
返回一个复制的文件描述符,返回的描述符指向的文件和描述符fd指向的文件是一致的。
os.dup2(fd, fd2)
复制一个描述符fd,产生一个描述符fd2,如果fd2指向的文件打开着,则关闭该文件,使得释放这个被占用的文件描述符。
os.fchmod(fd, mode)
改变一个文件的访问权限,该文件由参数fd指定,参数mode是unix下的文件访问权限。相当于unix下的chmod命令,只是这里是系统提供的一个改变文件权限的接口,文件权限包括”rwx”表示的读,写,执行权限,以及针对用户的”ugo“三个对象,表示拥有者用户,组用户,其他用户。
os.fchown(fd, uid, gid)
修改一个文件的所有权,这个函数修改一个文件的用户id和用户组id,该文件由文件描述符fd指示。如果uid和gid中任何一个设置为-1,则表示不对其进行修改。
os.fdatasync(fd)
强制将文件写入磁盘,该文件由文件描述符fd指示,但是不强制更新文件的状态信息。
os.fstat(fd)
返回包含了文件描述符fd指向的文件的文件信息,这个函数的实现和stat()系统调用是一样的,返回文件的信息:
st_mode - 文件信息的掩码,包含了文件的权限信息,文件的类型信息(是普通文件还是管道文件,或者是其他的文件类型)
st_ino - 文件的i-node值
st_dev - 设备信息
st_nlink - 硬连接数
st_uid - 用户id
st_gid - 组id
st_size - 文件大小,以byte为单位
st_atime - 文件最近的访问时间
st_mtime - 文件最近的修改时间
st_ctime - 文件状态信息的修改时间(不是文件内容的修改时间)
不同的unix系统上可能还会有一写扩展的信息可供调用。如在linux系统上,还包含了如下的一些信息:
st_blocks - 文件的是由多少个 512 byte 的块构成的
除了上述的fstat()函数,os模块还包含了stat(),lstat()等函数,用于获取文件信息。
os.ftruncate(fd, length)
将文件大小截断为length字节长度,如果length指定为0,则相当于在os.open()一个文件的时候指定os.o_trunc选项,文件描述符指示截断的文件。
os.isatty(fd)
检查一个文件描述符fd指示的文件是否是一个tty字符设备文件,如果是,则返回true,否则返回false。
os.lseek(fd, pos, how)
设置文件偏移位置,文件由文件描述符fd指示。这个函数依据how参数来确定文件偏移的起始位置,pos参数指定位置的偏移量。
how参数的值为:
os.seek_set - 文件的开头, 可以用 0 代替
os.seek_cur - 当前的文件偏移处, 可以用 1 代替
os.seek_end - 文件结尾, 可以用 2 代替
os.open(file, flags[, mode])
打开一个文件,并且设置需要的打开选项,mode参数是可选的,如果flags选项中包含了os.o_creat选项,则需要指定mode参数,指示文件创建时使用的权限。函数返回一个文件描述符,用于对该文件的访问。
flags常用参数(可以参看linux man-page open(2)):
os.o_rdonly - 文件以只读方式打开
os.o_wronly - 文件以只写方式打开
os.o_rdwr - 文件以读写方式打开
os.o_append - 文件以添加方式打开
os.o_trunc - 文件大小截断为0
os.o_creat - 如果文件不存在,则创建文件
os.o_excl - 如果文件存在,并且指定了os.o_creat,则在指定该选项的情况下os.open调用会抛出oserror异常。
这个os.open()调用是一个低层的i/o调用,相当于在c api中的open系统调用。在使用的时候可以使用python内建的open函数,该函数是对这个低层i/o的封装。
os.pipe()
创建一个用于父子进程间通信的管道,返回一个二元组(read_fd, write_fd),read_fd指示创建的管道的读描述符,write_fd指示创建的管道的写描述符。关于linux下管道的信息,可以参看 ipc-管道 。
os.read(fd, n)
从fd指示的文件中读取最多n个字节的数据,函数返回一个包含读取内容的字符串对象。如果读取到文件尾,则返回一个空字符串对象。
os.write(fd, str)
将字符串str写入到文件中,文件描述符fd指示处理的文件,函数返回实际写入的字节个数。
文件和目录操作
os.access(path, mode)
使用实际的uid和gid去测试路径的访问权。实际的uid和gid指的是用户登录到系统使用的uid和当前用户所在的gid,这和有效用户id和有效组id是有区别的,有效用户id和有效组id是对应于进程的。
mode参数指定测试路径的方式:
os.f_ok - 测试路径是否存在
os.r_ok - 测试文件是否可读
os.w_ok - 测试文件是否可写
os.x_ok - 测试文件是否可执行
其中的r_ok,w_ok,x_ok是可以使用or操作合起来进行一起测试的。
函数返回true如果测试成功,否则返回false。在系统的c api中可以使用access系统调用。
os.chdir(path)
切换当前的工作目录为path指定的目录,相当于linux下cd命令的功能。
os.fchdir(fd)
通过文件描述符切换当前的工作目录到文件描述符指示的目录,fd参数必须指向打开的目录,不能是文件。
os.getcwd()
以字符串的形式返回当前的工作目录。
os.chroot(path)
切换当前进程的root目录到指定的path路径下,这个函数可以方便的为当前的进程创建一个自定义的运行环境,如果想创建一个沙盒运行环境,这个函数就很有用,功能类似于linux下的chroot命令。
os.chmod(path, mode)
修改路径的权限,mode参数指定了需要设置的权限。这个函数和os.fchmod()功能一致,区别是os.fchmod处理的是一个文件描述符,也就是说需要先打开一个文件获取该文件的文件描述符后才可以进行操作,而os.chmod()直接在文件名上进行操作。
mode参数定义在 stat 模块中:
stat.s_isuid – 设置用户id
stat.s_isgid - 设置用户组id
stat.s_isvtx - 设置粘滞位,目前只对目录有效,相当于在linux中的sbit位。
stat.s_irusr - 设置用户读权限位
stat.s_iwusr - 设置用户写权限位
stat.s_ixusr - 设置用户执行权限位
stat.s_irwxu - 相当于是s_irusr,s_iwusr,s_ixusr的or运算的值
stat.s_irgrp - 设置组读权限位
stat.s_iwgrp - 设置组写权限位
stat.s_ixgrp - 设置组执行权限位
stat.s_irwxg - 相当于是s_irgrp,s_iwgrp,s_ixgrp的or运算的值
stat.s_iroth - 设置其他用户的读权限
stat.s_iwoth - 设置其他用户的写权限
stat.s_ixoth - 设置其他用户的执行权限
stat.s_irwxo - 相当于是s_iroth,s_iwoth,s_ixoth的or运算的值
os.chown(path, uid, gid)
设置文件的用户id和组id,和os.fchown()类似,区别是后者接受的是一个文件描述符。如果不需要修改,则在指定的id位置设置为-1。
os.lchmod(path, mode)
修改文件的权限属性,如果path指示的路径是一个符号链接,则只会作用于该符号链接自身,不会修改其连接的源文件。
os.lchown(path, uid, gid)
修改文件的uid和gid,和os.chown()函数功能一样,区别是如果path指示的路径是一个符号链接,则只会修改符号链接自身,不会修改其连接的源文件。
os.link(source, link_name)
给文件source创建一个硬连接link_name,相当于linux中的不叫-s选项的ln命令。
os.listdir(path)
返回一个由path指定的目录中的所有文件组成的列表。返回的列表是没有经过排序的。并且返回的列表中不包含‘.’和‘..’这两项。这个是一个很实用的函数。
os.lstat(path)
stat()系列函数中的一个,如果path指定的是一个符号链接,则该函数只会处理该符号链接自身,不会处理该链接的源文件。
os.mkinfo(path[, mode])
创建一个fifo有名管道,相当于linux下c api中的mkfifo()系统调用。mode参数指定了有名管道创建时指定的权限。和os.pipe()类似,只不过os.pipe()创建的是一个无名管道,只能用于有亲缘关系的进程间通信,而fifo有名管道可以在两个没有任何亲缘关系的管道间通信,只要指定path就可以了。关于linux下管道的内容,可以参看 ipc-管道 。
os.mkdir(path[, mode])
创建一个名为path的目录,同时可以指定mode权限。当设置mode权限的时候,需要和系统中的umask掩码进行运算,最后才是目录的权限。如果mode没有指定,则其值为0777。如果将要创建的目录已经存在,则会抛出os.oserror异常。
os.makedirs(path[, mode])
递归地创建目录,和os.mkdir()函数类似,区别是该函数可以递归地创建多级目录。在创建过程中,如果子目录已存在或者该目录无法创建,则会抛出一个oserror异常。
os.readlink(path)
读一个符号链接,返回一个字符串对象,表示符号链接的源文件的位置。返回的结果可能是一个绝对路径,也可能是一个相对路径。
os.remove(path)
删除一个文件,文件由path指定。如果path指定的是一个目录,则抛出一个oserror异常。在unix下,该函数会先删除该文件名,如果该文件还在被别的进程使用,则该文件占据的空间还是会被保留,知道没有进程使用这个文件。和os.unlink()的工作机制一样。
os.removedirs(path)
递归地删除目录,和os.rmdir()类似,区别是os.removedirs()可以删除非空目录。os.removedirs()尝试连续地删除每一个在path中给定的父目录直到一个错误被抛出,但是该错误通常被忽略,因为这一般意味着这个父目录是非空的。例如:当path指定为“foo/bar/baz”的时候,先删除目录“foo/bar/baz”如果非空的话,然后删除“foo/bar”如果非空的话,最后删除“foo”如果该目录是空的。如果无法连续的删除给定的目录,则抛出一个oserror异常。
os.rename(src, dst)
对文件或目录进行重命名,如果dst指定的是一个目录,则会抛出一个oserror异常。在unix系统中,如果dst是一个已经存在的文件,则会替换该文件如果权限允许的话。在一些unix系统中可能会失败如果src和dst是在不同的文件系统上。如果可以成功操作,则该操作是一个原子操作。
os.renames(old, new)
递归地对目录进行更名,也可以对文件进行更名。和os.rename()的区别是,该函数会自动创建所有的中间目录,在创建中间目录的过程中,每创建好一个新目录后使用os.removedirs()删除对应的旧目录。
注意:这个函数可能会在创建新的目录结构的时候操作失败,如果在删除旧目录的过程中出现删除权限问题。
os.rmdir(path)
删除path指定的空目录,如果目录非空,则抛出一个oserror异常。
os.stat(path)
获取path指定的路径的信息,功能等同于c api中的stat()系统调用。该函数是stat函数族中的一种,和前述的lstat(),fstat()函数类似,只不过stat()函数处理的是目录,而且遇到符号链接的时候是处理符号链接的源文件的,而不是符号链接自身。
os.symlink(source, link_name)
为源文件source创建一个符号链接link_name。
os.unlink(path)
删除一个path指定的文件,和os.remove()的工作机制一样。
os.utime(path, times)
修改文件的访问时间和修改时间。如果times参数为none,则设置文件的访问时间和修改时间为当前的时间。否则,如果times参数不为空,则times参数是一个二元组(atime, mtime),用于设置文件的访问时间和修改时间。
os.tempnam([dir[, prefix]])
返回一个独一无二的路径名作为临时文件的文件名。返回的路径名是一个绝对路径,该临时文件名的入口由dir参数指定,如果dir参数没有指定或者为none,则用通用的临时文件目录作为临时文件的目录。如果dir被指定,并且不是none,则prefix参数被用来作为创建的临时文件名的前缀。
os.tmpnam()
返回一个独一无二的路径名作为临时文件的文件名,该文件名被创建者通用的临时文件目录下。
注意:os.tmpnam()和os.tempnam()只是负责生产一个临时文件的路径名,而不负责文件的创建和删除。
os.walk(top, topdown = true, onerror = none, followlinks = false)
以自顶向下遍历目录树或者以自底向上遍历目录树,对每一个目录都返回一个三元组(dirpath, dirnames, filenames)。
三元组(dirpath,dirnames,filenames):
dirpath - 遍历所在目录树的位置,是一个字符串对象
dirnames - 目录树中的子目录组成的列表,不包括("."和"..")
filenames - 目录树中的文件组成的列表
如果可选参数topdown = true或者没有指定,则其实目录的三元组先于其子目录的三元组生成(自顶向下生成三元组),如果topdown = false,则起始目录的三元组在其子目录的三元组生成后才生成(自底向上生成三元组)。
当topdown = true,os.walk()函数会就地修改三元组中的dirnames列表(可能是使用del或者进行切片),然后再使用os.walk()递归地处理剩余在dirnames列表中的目录。这种方式有助于加快搜索效率,可以指定特殊的遍历顺序。当topdown = false的时候修改dirnames是无效的,因为在使用自底向上进行遍历的时候子目录的三元组是先于上一级目录的三元组创建的。
默认情况下,调用listdir()返回的错误会被忽略,如果可选参数oneerror被指定,则oneerror必须是一个函数,该函数有一个oserror实例的参数,这样可以允许在运行的时候即使出现错误的时候不会打断os.walk()的执行,或者抛出一个异常并终止os.walk()的运行。
默认情况下,os.walk()遍历的时候不会进入符号链接,如果设置了可选参数followlinks = true,则可以进入符号链接。
注意:当设置followlinks = true时,可能会出现循环遍历,因为符号链接可能会出现自己链接自己的情况,而os.walk()不会意识到这一点。
注意:如果传递过去的路径名是一个相对路径,则不会修改当前的工作路径。
使用os.walk遍历目录真的很方便:
复制代码
#-*- coding:utf-8 -*-
import os
if __name__ == '__main__':
try:
'''traval and list all files and all dirs'''
for root, dirs, files in os.walk('d:' + os.sep + 'python27'):
print '-------------------directory < ' + root + ' > --------------------------'
for d in dirs:
print d
for f in files:
print f
except oserror, e:
print os.strerror(e.errno)
复制代码