Python 目录管理

来自CloudWiki
跳转至: 导航搜索

背景介绍

  • 寻找‘危险’文件
  • 寻找大文件
  • 比较两个目录
  • 深度遍历目录
  • 统计目录占用空间

引入模块

import os
import filecmp

具体操作

查看当前目录

>>> os.getcwd()
'C:\\Users\\maxin\\AppData\\Local\\Programs\\Python\\Python37'
>>> 

创建目录

>>> t=os.getcwd()+"\\temp2"

>>> os.mkdir(t)

创建多级目录 os.makedirs(r"c:\python\test")

切换目录

>>> os.chdir(os.getcwd()+'\\temp')

>>> os.getcwd()

'C:\\Users\\maxin\\AppData\\Local\\Programs\\Python\\Python37\\temp'

>>> os.chdir('..')

遍历目录内容

>>> os.listdir('.')

>>> os.listdir(r'D:\teaching\自动化运维\练习')

['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']

案例:寻找‘危险’文件:

链接:危险文件有哪些 ?

import os
for fname in os.listdir(r'd:\\654'):
    if fname.endswith(('.exe','.com','.pif','.bat','.scr')):
        print('发现危险文件 ',fname)

改进版1:建立危险文件库

import os
store = ('.exe','.txt')
for fname in os.listdir(r'd:\\'):
    if fname.endswith(store):
        print('发现危险文件 ',fname)

改进版2:列表推导式

>>> [fname for fname in os.listdir('.')if fname.endswith(('.exe', '.txt'))]

['LICENSE.txt', 'NEWS.txt', 'python.exe', 'pythonw.exe']

列表推导式 详见:Python列表

应用:Python实例:制作图片电子书

删除目录

>>> os.listdir('.')

['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'temp', 'Tools', 'vcruntime140.dll']

>>> os.rmdir('temp')

>>> os.listdir('.')

['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python37.dll', 'pythonw.exe', 'Scripts', 'tcl', 'Tools', 'vcruntime140.dll']

查看目录空间占用情况

查看某文件大小:

>>> os.path.getsize(r'd://pythonw.exe')
98320

以兆为单位查看:

os.path.getsize(r"D:\teaching\自动化运维\练习\data_etr.csv")/1024/1024

案例:计算单层目录占用空间

import os
mydir = '.'
total =0
for fname in os.listdir(mydir):

    sub_path = os.path.join(mydir, fname)#获得每个文件路径

    if os.path.isfile(sub_path):
        
        size =(os.path.getsize(sub_path))/1024/1024 #换算成MB

        total +=size

print("该目录所有文件占据:"+str(total)+"MB 空间")

案例:寻找大文件!

import os
mydir = r'D:\Game\2020校赛'
for fname in os.listdir(mydir):

    sub_path = os.path.join(mydir, fname)

    if os.path.isfile(sub_path):

        size =(os.path.getsize(sub_path))/1024 #换算成KB

        if size >100:

            print(fname,":",size,"KB") 
 

输出结果:

LICENSE.txt
NEWS.txt
python.exe
pythonw.exe

改进版:寻找D盘大于500M的文件

import os
mydir = r'D:\\'
emit_dir ={"System Volume Information","Config.Msi","Program Files","$RECYCLE.BIN"}
def findBig(dir):
    for fname in os.listdir(dir):

        sub_path = os.path.join(dir, fname)

        if os.path.isfile(sub_path):

            size =(os.path.getsize(sub_path))/1024/1024 #换算成MB

            if size>500:
                size =round(size,2)
                print(sub_path,":",size,"MB")
        elif  fname not in emit_dir:
            findBig(sub_path)

if __name__ == "__main__" :
    findBig(mydir)

比较两个目录

filecmp模块能够实现两个文件夹的比较。

背景

test1目录:data.txt、sample.txt

test2目录:data_asc.txt、sample.txt

使用方法

调用:

import filecmp
a =r"D:\teaching\自动化运维\2021-2022-2\上星期"
b =r"D:\teaching\自动化运维\2021-2022-2\这星期"
dirobj =filecmp.dircmp(a,b)
print(dirobj.report())

输出对比结果:

dirobj.report() # report(),比较当前指定目录中的内容

diff test1 test2
Only in test1 : ['data.txt']
Only in test2 : ['data_asc.txt']
Identical files : ['sample.txt']

输出分类对比结果

print("common:"+str(dirobj.common)) # common,两边目录共同存在的文件或目录

print("left_only:"+str(dirobj.left_only)) # 只在左目录中的文件或目录

print("right_only:"+str(dirobj.right_only)) # 只在右边目录中的文件或目录

common:['sample.txt']
left_only:['data.txt']
right_only:['data_asc.txt']

遍历目录下所有子目录和文件

深度遍历

Python2020-7-2.png

递归:Python函数的递归

from os import listdir
from os.path import join, isfile, isdir

def listDirDepthFirst(directory):
    '''深度优先遍历文件夹'''
    #遍历文件夹,如果是文件就直接输出
    #如果是文件夹,就输出显示,然后递归遍历该文件夹
    for subPath in listdir(directory):
        path = join(directory, subPath)#【绝对路径】
        if isfile(path):#【判断是否是文件】
            print(path)
        elif isdir(path):#【判断是否是目录】
            print(path)
            listDirDepthFirst(path)

if __name__ =='__main__':
    listDirDepthFirst(r'D:\teaching\自动化运维\2021-2022-2')

案例:实现文件的搜索功能

 
from os import listdir
from os.path import join, isfile, isdir
def listDirDepthFirst(directory,keyword):
    '''深度优先遍历文件夹'''
    #在特定目录搜索带关键字的文件
    for subPath in listdir(directory):
        path = join(directory, subPath)#【绝对路径】
        if isfile(path) :#【判断是否是文件】
            if keyword in path:
                print(path)
        elif isdir(path):#【判断是否是目录】
            #print(path)
            listDirDepthFirst(path,keyword)

if __name__ =='__main__':
    while True:
        keyword = input("请输入查找关键字:")
        listDirDepthFirst('.',keyword)

广度遍历

Python2020-7-3.png

Python2020-7-1.png

下面的代码使用了广度优先遍历方法。

from os import listdir
from os.path import join, isfile, isdir

def listDirWidthFirst(directory):
    '''广度优先遍历文件夹'''
    #使用列表模拟双端队列,效率稍微受影响,不过关系不大
    dirs = [directory]#这个directory就是列表的第一个元素
    #如果还有没遍历过的文件夹,继续循环
    while dirs:
        #遍历还没遍历过的第一项
        current = dirs.pop(0)
        #遍历该文件夹,如果是文件就直接输出显示
        #如果是文件夹,输出显示后,标记为待遍历项
        for subPath in listdir(current):
            path = join(current, subPath)
            if isfile(path):
                print(path)
            elif isdir(path):
                print(path)
                dirs.append(path)

if __name__ =='__main__':
    listDirWidthFirst(r'D:\teaching\自动化运维\2021-2022-2')


应用:统计目录占用空间

本程序为目录管理的一个典型应用,

对统计电脑中每个文件夹(目录)占用空间的大小。

除了应用目录管理有关命令外,还用到了递归思想 和 函数调用的有关知识,请仔细体会。

关于递归思想,这里有一个小讲义:Python函数的递归,大家不清楚递归的 可以看一下。

import os

totalSize = 0
fileNum = 0
dirNum = 0

#统计函数,递归的遍历每个文件夹
def visitDir(path):
    global totalSize
    global fileNum
    global dirNum
    for lists in os.listdir(path):
        sub_path = os.path.join(path, lists)
        if os.path.isfile(sub_path):
            fileNum = fileNum+1                              #统计文件数量
            totalSize = totalSize+os.path.getsize(sub_path)  #统计文件总大小
        elif os.path.isdir(sub_path):
            dirNum = dirNum+1                                #统计文件夹数量
            visitDir(sub_path)                               #递归遍历子文件夹

#主函数
def main(path):
    if not os.path.isdir(path):
        print('Error:"', path, '" is not a directory or does not exist.')
        return
    visitDir(path)

#单位换算函数
def sizeConvert(size):                                   #单位换算
    K, M, G = 1024, 1024**2, 1024**3
    if size >= G:
        return str(size/G)+'G Bytes'
    elif size >= M:
        return str(size/M)+'M Bytes'
    elif size >= K:
        return str(size/K)+'K Bytes'
    else:
        return str(size)+'Bytes'

#输出函数
def output(path):
    print('The total size of '+path+' is:'+sizeConvert(totalSize)
          +'('+str(totalSize)+' Bytes)')
    print('The total number of files in '+path+' is:',fileNum)
    print('The total number of directories in '+path+' is:',dirNum)

if __name__=='__main__':
    path = r'D:\teaching\自动化运维'
    main(path)
    output(path)

应用:复制空目录

云盘备份:有的时候需要将云端的目录结构复制到本地