Python中的文件和目录操作实现代码


Posted in Python onMarch 13, 2011

本文将详细解释这些函数的使用方法。首先,我们介绍Python语言中类似于Windows系统的dir命令的列出文件功能,然后描述如何测试一个文件名对应的是一个标准文件、目录还是链接,以及提取文件大小和日期的方法。之后,我们还将介绍如何删除文件和目录,如何复制和删除文件,以及怎样将一个完整的文件路径分解成目录部分和文件名部分,最后,我们讲解目录的创建,以及如何在目录树中移动目录并处理文件。

一、显示目录内容

当我们想要列出当前目录中所有扩展名为.jpg或.gif的文件的时候,就可以使用glob模块来完成此项任务,如下所示:

import glob

filelist = glob.glob('*.jpg') + glob.glob('*.gif')

上述代码使用了glob函数,该函数的参数为要显示的文件类型。在这里,文件类型是通过类似UNIX操作系统shell风格通配符描述的一些文件名来指定的。这些通配符的使用方法,具体请参考fnmatch模块的文档,那里有具体的说明和示例。

为了显示一个目录中的全部文件,可以使用如下所示的os.listdir函数:

files = os.listdir(r'C:\hpl\scripting\src\py\intro') #适用于 Windows 

files = os.listdir('/home/hpl/scripting/src/py/intro') # 适用于Unix 

# 跨平台版本: 

files = os.listdir(os.path.join(os.environ['scripting'], 

'src', 'py', 'intro')) 

files = os.listdir(os.curdir) # 当前目录中的所有文件 

files = glob.glob('*') + glob.glob('.*')

二、测试文件类型

我们知道,文件名、目录名和链接名都是用一个字符串作为其标识符的,但是给我们一个标识符,我们该如何确定它所指的到底是常规文件文件名、目录名还是链接名呢?这时,我们可以使用os.path模块提供的isfile函数、isdir函数和islink函数来达成我们的目标,如下所示:

print myfile, '是一个', 
if os.path.isfile(myfile): 

print 'plain file' 

if os.path.isdir(myfile): 

print 'directory' 

if os.path.islink(myfile): 

print 'link'

您还可以查找文件的日期及其大小:

time_of_last_access = os.path.getatime(myfile) 

time_of_last_modification = os.path.getmtime(myfile) 

size = os.path.getsize(myfile)

这里的时间以秒为单位,并且从1970年1月1日开始算起。为了获取以天为单位的最后访问日期,可以使用下列代码:

import time # time.time()返回当前时间

age_in_days = (time.time()-time_of_last_access)/(60*60*24)

为了获取文件的详细信息,可以使用os.stat函数和stat模块中的其它实用程序来达到目的,如下:

import stat 

myfile_stat = os.stat(myfile) 

size = myfile_stat[stat.ST_SIZE] 

mode = myfile_stat[stat.ST_MODE] 

if stat.S_ISREG(mode): 

print '%(myfile)是一个常规文件,大小为 %(size)d 字节' %\ 

vars()

有关stat模块的详细信息,请参见Python Library Reference。若想测试一个文件的读、写以及执行权限,可以用os.access函数,具体如下所示:

if os.access(myfile, os.W_OK):

print myfile, '具有写权限'

if os.access(myfile, os.R_OK | os.W_OK | os.X_OK):

print myfile, '具有读、写以及执行权限'

像上面这样的测试代码,对CGI脚本来说非常有用。

三、文件和目录的删除

若要删除单个文件的话,可以使用os.remove函数,例如:os.remove('mydata.dat')。Os.remove的别名是os.unlink,不过后者跟传统的UNIX操作系统以及Perl中清除文件的函数重名。我们可以使用下列方式来删除一组文件,如所有以.jpg以及*.gif为扩展名的文件:

for file in glob.glob('*.jpg') + glob.glob('*.gif'):

os.remove(file)

大家知道,只有当目录中内容已经被清空的时候,我们才可以使用rmdir命令来删除该目录。不过,我们经常想要删除一个含有许多文件的目录树,这时我们可以使用shutil模块提供的rmtree函数,如下所示:

shutil.rmtree('mydir')

它相当于UNIX操作系统中的命令rm -rf mydir。

我们可以建立一个自定义函数,使其在进行删除操作的时候将文件和目录做同等对待,其典型用法如下所示:

remove('my.dat') #删除当个文件my.dat

remove('mytree') #删除单个目录树 mytree

# 通过字符串列表中的名称来删除多个文件/目录树:

remove(glob.glob('*.tmp') + glob.glob('*.temp'))

remove(['my.dat','mydir','yourdir'] + glob.glob('*.data'))

下面是remove函数的实现:

def remove(files):

"""删除一个或多个文件和/或目录。"""

if isinstance(files, str): # files是个字符串吗?

files = [files] # 把files从字符串转为列表

if not isinstance(files, list): # files不是列表吗?


for file in files:

if os.path.isdir(file):

shutil.rmtree(file)

elif os.path.isfile(file):

os.remove(file)

下面测试一下remove函数的灵活性:

# 建立10个目录tmp_* ,以及10各文件tmp__*: 

for i in range(10): 

os.mkdir('tmp_'+str(i)) 

f = open('tmp__'+str(i), 'w'); f.close() 

remove('tmp_1') # tmp_1为目录 

remove(glob.glob('tmp_[0-9]') + glob.glob('tmp__[0-9]'))

作为上述remove函数实现的一个注记,我们进行了下列测试:

if not isinstance(files, list):

它实际上是过于严厉。我们需要的只是一个被遍历的一个文件/目录名序列。实际上,我们并不关心名称是否存储在一个列表、元组或者数值数组中,所以更好的测试应该像下面这样:

if not operator.isSequenceType(files):


四、文件的复制与重命名

当我们要复制文件的时候,可以使用shutil模块:

import shutil

shutil.copy(myfile, tmpfile)

#拷贝最后访问时间和最后修改时间:

shutil.copy2(myfile, tmpfile)

# 拷贝一个目录树:

shutil.copytree(root_of_tree, destination_dir, True)

Copytree的第三个参数规定对符号链接的处理,其中True表示保留符号链接;而False则意味着使用文件的物理副本替代符号链接。

Python语言能够很好地支持路径名的跨平台组成:Os.path.join能使用正确的分界符(在UNIX和Mac OS X操作系统中使用/,在 Windows 上使用\)来联接目录和文件名,变量os.curdir和os.pardir分别表示当前工作目录及其父目录。 像下面的UNIX操作系统命令

cp https://3water.com/f1.c .

可以使用Python语言提供一个跨平台的实现:

shutil.copy(os.path.join(os.pardir,os.pardir,'f1.c'), os.curdir)

Os模块中的rename函数通常被用于重命名一个文件:

os.rename(myfile, 'tmp.1') # 将myfile重命名为'tmp.1'

这个函数也可用来在相同的文件系统之内移动文件。这里,我们将myfile移动到目录d下面:

os.rename(myfile, os.path.join(d, myfile))

在跨文件系统移动文件的时候,可以先使用shutil.copy2来复制文件,然后再删除原来的副本即可,如下:

shutil.copy2(myfile, os.path.join(d, myfile))

os.remove(myfile)

后面这种移动文件的方法是最安全的。

五、分解路径名

假设我们使用变量fname来存放一个包含完整路径的文件名,例如:

/usr/home/hpl/scripting/python/intro/hw.py

有时候,我们需要将这样的文件路径拆分为基本名称hw.py和目录名/usr/home/hpl/scripting/python/intro。在Python语言中,可以使用下列代码达到目的:

basename = os.path.basename(fname)

dirname = os.path.dirname(fname)

# 或

dirname, basename = os.path.split(fname)

扩展名是通过os.path.splitext函数提取出来的,

root, extension = os.path.splitext(fname)

这样,fname中的扩展名部分即.py被赋给变量extension,而其余部分则赋给了变量root。如果想得到不带点号的扩展名的话,只需使用os.path.splitext(fname)[1][1:]即可。

假设一个文件名为f,其扩展名随意,若想将其扩展名改为ext,可以使用下面的代码:

newfile = os.path.splitext(f)[0] + ext

下面是一个具体的示例:

>>> f = '/some/path/case2.data_source'

>>> moviefile = os.path.basename(os.path.splitext(f)[0] + '.mpg')

>>> moviefile

'case2.mpg'

六、目录的创建和移动

Os模块中的函数mkdir可以用来创建目录,而chdir函数则可以移动目录,如下:

origdir = os.getcwd() # 将当前位置记下来

newdir = os.path.join(os.pardir, 'mynewdir')

if not os.path.isdir(newdir):

os.mkdir(newdir) # 或者os.mkdir(newdir,'0755')

os.chdir(newdir)

...

os.chdir(origdir) # 返回原目录

os.chdir(os.environ['HOME']) # 移到主目录

假设我们想要在自己的主目录下创建一个新目录py/src/test1,但是目前py、src和test1都不存在。如果使用mkdir命令来创建的话,需要使用三次才能建好这个嵌套的目录,但是使用Python语言提供的os.makedirs命令的话,则无需这样麻烦了,该命令可以一次建好整个目录:

os.makedirs(os.path.join(os.environ['HOME'],'py','src','test1'))

七、遍历目录树

下面的函数调用

os.path.walk(root, myfunc, arg)

将遍历root目录树;然后,对每个目录名dirname分别调用myfunc(arg, dirname, files)即可,这里参数files是dir中的文件名列表(可通过调用os.listdir(dirname)来获得);arg是用户从调用代码中传递来的参数。对于UNIX操作系统用户来说,Python语言中跨平台的os.path.walk相当于Unix命令find。

在解释os.path.walk的用法的时候,人们常使用写出主目录中所有子目录内的文件的名称为例进行说明。当然,我们也可以在一个交互式的Python命令行中使用下列代码段来体会os.path.walk的使用:

def ls(arg, dirname, files):

print dirname, 'has the files', files

os.path.walk(os.environ['HOME'], ls, None)

本例中,参数arg并非必需,所以在os.path.walk调用中让其取值为None即可。

为了列出主目录中所有大于1Mb的文件,可以使用下面的代码:

def checksize1(arg, dirname, files):

for file in files:

filepath = os.path.join(dirname, file)

if os.path.isfile(filepath):

size = os.path.getsize(filepath)

if size > 1000000:

size_in_Mb = size/1000000.0

arg.append((size_in_Mb, filename))

bigfiles = []

root = os.environ['HOME']

os.path.walk(root, checksize1, bigfiles)

for size, name in bigfiles:

print name, '大小为', size, 'Mb'

现在,我们使用arg来建立一个数据结构,这里是一个2元组构成的列表,其中每个2元组存放文件的尺寸(以MB为单位)和完整的文件路径。如果用于所有目录的函数调用中都要更改arg的话,那么arg必须是一个可变的数据结构,即允许适当地进行修改。

参数dirname是当前正在访问的目录的绝对路径,而参数files内的文件名则是相对于dirname的相对路径。在此期间,当前工作目录并没有改变,那就是说该脚本仍然呆在脚本启动时刻所在的目录中。这就是为什么我们需要把filepath弄成带有dirname和file的绝对路径的原因。若要改变当前工作目录为dirname,只要在针对每个目录调用os.path.walk的函数中调用一下os.chdir(dirname),然后在该函数的末尾重新调用os.chdir(dirname)将当前工作目录改回原值即可,如下所示:

def somefunc(arg, dirname, files):

origdir = os.getcwd(); os.chdir(dirname)


os.chdir(origdir)

os.path.walk(root, somefunc, arg)

当然,如果您愿意也可以编写具有类似功能的代码来替代os.path.walk。下面的代码,将针对每个文件而非每个目录来调用的自定义函数,如下所示:

def find(func, rootdir, arg=None):

# 对rootdir目录中的每个文件调用func

files = os.listdir(rootdir) # 获取rootdir目录中的所有文件

files.sort(lambda a, b: cmp(a.lower(), b.lower()))

for file in files:

fullpath = os.path.join(rootdir, file)

if os.path.islink(fullpath):

pass

elif os.path.isdir(fullpath):

find(func, fullpath, arg)

elif os.path.isfile(fullpath):

func(fullpath, arg)

else:

print 'find: cannot treat ', fullpath

上面的函数find可以从scitools模块中获取。与内置函数os.path.walk相反,我们的find函数以大小写敏感的字母顺序来访问文件和目录。

我们可以使用find函数来列出所有大于1Mb的文件:

def checksize2(fullpath, bigfiles):

size = os.path.getsize(fullpath)

if size > 1000000:

bigfiles.append('%.2fMb %s' % (size/1000000.0, fullpath))

bigfiles = []

root = os.environ['HOME']

find(checksize2, root, bigfiles)

for fileinfo in bigfiles:

print fileinfo

参数arg带来了巨大的灵活性。我们可以使用它来同时存放输入数据和生成的数据结构。下一个范例将收集所有大于一定尺寸的带有规定扩展名的文件的文件名和大小。输出的结果按照文件大小排列。

bigfiles = {'filelist': [], # 文件名和大小列表

'extensions': ('.*ps', '.tiff', '.bmp'),

'size_limit': 1000000, # 1 Mb

}

find(checksize3, os.environ['HOME'], bigfiles)

def checksize3(fullpath, arg):

treat_file = False

ext = os.path.splitext(fullpath)[1]

import fnmatch # Unix的shell风格的通配符匹配

for s in arg['extensions']:

if fnmatch.fnmatch(ext, s):

treat_file = True # fullpath带有正确的扩展名

size = os.path.getsize(fullpath)

if treat_file and size > arg['size_limit']:

size = '%.2fMb' % (size/1000000.0) # 打印

arg['filelist'].append({'size': size, 'name': fullpath})

# 按照大小排列文件

def filesort(a, b):

return cmp(float(a['size'][:-2]), float(b['size'][:-2]))

bigfiles['filelist'].sort(filesort)

bigfiles['filelist'].reverse()

for fileinfo in bigfiles['filelist']:

print fileinfo['name'], fileinfo['size']

注意为列表排序的函数,bigfiles['filelist']函数中的每个元素就是一个字典,键size保存着一个字符串,不过在进行比较之前我们必须将单位Mb(最后两个字符)去掉,并将其转换为浮点数。

八、小结

对于文件和目录的处理,虽然可以通过操作系统命令来完成,但是Python语言为了便于开发人员以编程的方式处理相关工作,提供了许多处理文件和目录的内置函数。重要的是,这些函数无论是在Unix、Windows还是Macintosh平台上,它们的使用方式是完全一致的。本文详细解释了这些函数的使用方法,其中,我们首先介绍了显示目录内容的功能,然后描述如何测试一个文件名对应的是一个标准文件、目录还是链接,以及提取文件大小和日期的方法。之后,我们还将介绍如何删除文件和目录,如何复制和删除文件,以及怎样将一个完整的文件路径分解成目录部分和文件名部分,最后,我们讲解目录的创建,以及如何在目录树中移动目录并处理文件。

Python 相关文章推荐
python使用在线API查询IP对应的地理位置信息实例
Jun 01 Python
关于Python中浮点数精度处理的技巧总结
Aug 10 Python
pip install urllib2不能安装的解决方法
Jun 12 Python
python装饰器练习题及答案
Nov 01 Python
使用python实现数组、链表、队列、栈的方法
Dec 20 Python
Pytorch中的VGG实现修改最后一层FC
Jan 15 Python
Python求平面内点到直线距离的实现
Jan 19 Python
Python while循环使用else语句代码实例
Feb 07 Python
浅谈keras中的目标函数和优化函数MSE用法
Jun 10 Python
基于Python的接口自动化读写excel文件的方法
Jan 15 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
Mar 03 Python
python全面解析接口返回数据
Feb 12 Python
python 中的列表解析和生成表达式
Mar 10 #Python
Python中使用中文的方法
Feb 19 #Python
python实现的防DDoS脚本
Feb 08 #Python
Python牛刀小试密码爆破
Feb 03 #Python
初学python数组的处理代码
Jan 04 #Python
让python json encode datetime类型
Dec 28 #Python
让python的Cookie.py模块支持冒号做key的方法
Dec 28 #Python
You might like
什么是MVC,好东西啊
2007/05/03 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
javascript 获取模态窗口的滚动位置代码
2013/08/06 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
jQuery删除一个元素后淡出效果展示删除过程的方法
2015/03/18 Javascript
jQuery常用且重要方法汇总
2015/07/13 Javascript
javascript事件处理模型实例说明
2016/05/31 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
2016/07/07 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
jquery仿京东侧边栏导航效果
2017/03/02 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
深入浅析JS中的严格模式
2018/06/04 Javascript
零基础之Node.js搭建API服务器的详解
2019/03/08 Javascript
如何阻止小程序遮罩层下方图层滚动
2019/09/05 Javascript
javascript Canvas动态粒子连线
2020/01/01 Javascript
基于vue与element实现创建试卷相关功能(实例代码)
2020/12/07 Vue.js
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
Python文件夹与文件的操作实现代码
2014/07/13 Python
Python的组合模式与责任链模式编程示例
2016/02/02 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
python实现淘宝购物系统
2019/10/25 Python
俄罗斯鲜花递送:AMF
2020/04/24 全球购物
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
你的创业计划书怎样才能打动风投
2014/02/06 职场文书
商务经理岗位职责
2014/08/03 职场文书
单位工作证明范文
2014/09/14 职场文书
乔布斯辞职信(中英文对照)
2015/05/12 职场文书
贫民窟的百万富翁观后感
2015/06/09 职场文书
重阳节活动主持词
2015/07/04 职场文书
修辞手法有哪些?
2019/08/29 职场文书
Django实现在线无水印抖音视频下载(附源码及地址)
2021/05/06 Python
Oracle创建只读账号的详细步骤
2021/06/07 Oracle
Java 数组内置函数toArray详解
2021/06/28 Java/Android
宫崎骏十大动画电影,宫崎骏好看的动画电影排名
2022/03/22 日漫