天问

  • Blog
  • 热修复与动态加载
  • python爬虫
  • 专栏
    • 热修复与动态加载
    • NDK开发
    • 设计模式与架构
    • React Native
  • 好文转载
    • 计算机技术
    • 投资理财
    • 摄影与拍照技巧
  • 投稿
  • 关于本站及隐私政策
  • Github
StevenQ
为今天工作,为明天投资,为未来孵化一些东西!
  1. 首页
  2. 计算机技术
  3. python
  4. 正文

python遍历某个文件夹下的全部文件

2017年4月22日 1402点热度 4人点赞 1条评论

在前面的一小节中,我们谈到了对文件的读写操作,这一节我们谈谈使用python遍历某个文件夹下的全部文件,因为在实际的项目场景中这种情况非常常见,如在apk的逆向工程中可能需要在把dex文件反编译后产生的smali文件中查找某一特定的字符串,然后进行替换操作。这个场景很显然就涉及到了对某一文件夹下所有文件进行遍历的过程。这个过程很显然是对文件,目录,路径进行操作,而这些很显然是属于操作系统管理的范畴,因此这些功能被定义在了python中的os模块和os.path模块,使用前需要import相应的模块。这一小节就讲讲python中这两个模块常用的和文件操作相关的重要函数。

os模块

os.listdir(path)

该函数的功能是返回一个列表,该列表是path路径下的全部文件或者文件夹的名称,注意:返回的列表中是不会包含该path路径下的某个文件夹包含的子文件或者子文件夹,只会包含该路径下的文件夹与文件。path是传入的路径,通常是一个字符串。另外需要注意的是如果path不存在,会出现错误:WindowsError: [Error 3],系统找不到指定路径,因此使用该函数之前一定要对路径是否存在进行判断,代码如下:

if os.path.exists(dirPath):
    file_list=os.listdir(dirPath)

os.walk(top, topdown=True, onerror=None, followlinks=False)

该函数的功能是通过遍历top路径以生成一个目录树的文件名(Generate the file names in a directory tree by walking the tree)。该函数参数很多,但是后面几个参数都是带默认值参数,通常我们只需要关心第一个参数top,表示的是传入的top目录的路径。该函数返回一个三元组tuple(dirpath, dirnames, filenames),其中dirpath表示top路径下的全部目录的路径名称,通常是一个字符串,第二个参数表示的是dirpath目录下的全部子文件夹的名称列表(dirnames is a list of the names of the subdirectories in dirpath),filenames表示的是dirpath目录下的非文件夹文件的列表(filenames is a list of the names of the non-directory files in dirpath),需要注意的是第二个参数子目录名和第三个参数文件名都是没带根路径的,因此如果要得到完整的目录名或者文件名需要加上根路径dirpath。遍历某个文件夹下的全部文件的代码如下:

import os
dirPath='C:/Users/htq/Desktop/test'
for dirpath,dirnames,filenames in os.walk(dirPath):
    for file in filenames:
        print os.path.join(dirpath, file)#将dirpath和file连接起来得到完整的文件名

os.sep/os.linesep

  • os.sep 表示的是系统路径分隔符,在不同平台上表示不同,如windows平台上用'\\'表示而linux平台用'/'表示,因此为了保证我们所写的代码能够跨平台运行,请不要在程序中使用'\\'或者'/'来连接路径,而是使用os.sep
  • os.linesep表示的是行结束符,在不同的平台表示不同,如Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。另外在上一小节python文件操作中我们也提到了,write()和writelines()写入文件时是不包含行结束符的,因此如果需要在写入文件时插入行结束符的话需要我们要自己处理这些情况

os.path模块

os.path.exists(path)

该函数用来判断path路径指向的文件或者目录是否存在,如果不存在返回false

os.path.isdir(path)/os.path.isfile(path)

  • os.path.isdir(path)判断path是否为目录,如果是返回true否则返回false
  • os.path.isfile(path)判断path是否为文件,如果是返回true否则返回false

那么讲到这里,然后在根据前面我们提到的os模块的os.listdir(path),我们自然可以想到一种递归的方式来遍历某一路径下的全部文件,首先通过os.listdir(path)得到path路径下的全部文件,然后使用os.path.isdir(path)/os.path.isfile(path)来判断,如果该文件为目录那么我们递归调用,否则如果为文件,那么遍历输出,这样就可以实现和前面walk一样的效果。代码如下:

import os
def listDir(rootDir):
    if not os.path.exists(rootDir):
        return
    for dirname in os.listdir(rootDir):
        filename = os.path.join(rootDir, dirname)
        if (os.path.isfile(filename)):
            print filename
        else:
            listDir(filename)

虽然这中方式也可以实现遍历文件夹下的全部文件,但是因为使用的是递归的方式,效率应该比walk要低一些,另外从代码量上看也比使用walk要麻烦一些,唯一的好处就是从逻辑上理解起来比使用walk要清晰明了,因此尽量使用os.walk(path)的方式来替代这种方式。

os.path.join(path, *paths)

用来连接一个或多个目录与文件名/目录,前面说过在不同的平台上路径分隔符不同,因此为了做到跨平台,不要直接使用'\\'或者'/'的方式来连接目录与文件,应该使用os.sep的方式或者使用该函数,这样如果需要连接的字符串很多的时候会更简单

os.path.split(path)

该函数用来分割文件名和目录,如果path是目录,它会将最后一级目录作为文件名而分离,返回的是一个二元祖pair(head,tail),注意该函数不会判断路径是否存在,如果不存在也不会出错,但返回的结果可能不是我们预期的结果

os.path.splitext(path)

该函数用来分离文件名和扩展名,返回的是一个二元组pair(root,ext),其中root+ext==path,因此如果我们要得到一个文件的后缀类型需要这么使用:

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

这个函数的使用场景很多,如在遍历某一个文件夹下的某一特定类型的文件如.txt,.smali文件。

os.path.basename(path)

该函数用来得到path路径的文件名(如果path为目录则为目录名),如:path='C:/Users/htq/Desktop' 则返回'Desktop',path='C:/Users/htq/Desktop/test.py'则返回'test.py',如果path是以路径分隔符结尾,那么返回一个空字符串,如path='C:/Users/htq/Desktop/' ,则返回空字符串''。

代码实例

应用场景:将某一文件夹及其子文件夹下的全部的txt文件中的某个字符串替换为指定的字符串,这个实例综合了上一节和这一节的内容,在实际项目的文件操作中很常见。

import os

dirPath='C:/Users/htq/Desktop/test'
for dirpath,dirnames,filenames in os.walk(dirPath):
    for file in filenames:
        filename=os.path.join(dirpath, file)#将dirpath和file连接起来得到完整的文件名
        print filename
        if os.path.splitext(filename)[1]=='.txt':
            print filename
            try:
                with open(filename, 'r+') as fileObject:
                    lines = fileObject.readlines()
                    '''
                    for line in lines:#这中方式不能修改lines中的值,使用索引访问的方式才可以
                        line=line.replace('alibaba','tencent')
                        print line
                    '''
                    for index in range(len(lines)):  # 此处使用索引的方式访问,才可以修改原来的值
                        lines[index] = lines[index].replace('alibaba', 'tencent')
                    fileObject.seek(0)  # 让文件指针移动到文件开始位置,然后写入处理后的数据
                    fileObject.writelines(lines)
            except IOError, e:
                print 'could not open file:', e

 

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: python 文件操作
最后更新:2017年4月22日

天问

追梦追自由,穷则独善其身,达则兼济天下

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • Timothytok

    301 Moved Permanently
    301 Moved Permanently>>>

    2017年6月27日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    COPYRIGHT © 2022 天问 ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang