最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中線上目錄遍歷的避坑指南

 更新時間:2026年06月05日 08:28:40   作者:幸福清風  
做服務器運維、日志歸檔、磁盤巡檢、過期文件清理時,幾乎人人都要寫目錄遍歷腳本,線上目錄遠比本地測試環(huán)境復雜,本文小編為大家整理了一些Python中線上目錄遍歷的避坑方法,希望對大家有所幫助

前言

做服務器運維、日志歸檔、磁盤巡檢、過期文件清理時,幾乎人人都要寫目錄遍歷腳本。很多新手隨手os.listdir一層遍歷,本地測試幾個文件跑得飛快,一丟線上環(huán)境直接翻車:權限報錯中斷程序、軟鏈接無限遞歸死循環(huán)、海量小文件撐爆內(nèi)存、文件中途被刪除觸發(fā)異常崩潰。

線上目錄遠比本地測試環(huán)境復雜:數(shù)十萬細碎業(yè)務文件、帶空格/中文/特殊符號的文件名、無權限的緩存目錄、指向父級的軟鏈接、業(yè)務進程實時增刪文件,一套能扛住生產(chǎn)環(huán)境的遍歷代碼,核心從來不是實現(xiàn)遞歸,而是兜底各類異常、規(guī)避環(huán)境陷阱。

一、新手通用踩坑寫法:單層listdir,線上完全不堪用

最經(jīng)典的入門遍歷寫法,僅能讀取同級目錄,既無法遞歸深層目錄,也沒有任何異常捕獲,碰到權限目錄腳本直接PermissionError終止,也就是開篇日志卡在.cache權限目錄的根源。

import os
root = "/data/upload"
for name in os.listdir(root):
    path = os.path.join(root, name)
    print(path)

適用場景僅限本地臨時查看目錄,嚴禁用于生產(chǎn)文件統(tǒng)計、過期清理、磁盤巡檢。一旦遇到子目錄、權限隔離目錄、瞬時刪除的目錄,程序直接異常退出,前面掃描成果全部作廢。

二、生產(chǎn)優(yōu)選:os.scandir替代listdir,精準區(qū)分文件與目錄

os.scandir相比os.listdir優(yōu)勢巨大:返回DirEntry對象,自帶文件類型屬性,無需額外os.path.isdir/isfile重復系統(tǒng)IO,遍歷效率更高;搭配follow_symlinks=False屏蔽軟鏈接跟隨,從根源杜絕軟鏈接指向父目錄造成的無限遞歸。

單層安全遍歷模板,提前校驗路徑是否存在、是否為目錄,非法路徑直接日志跳過:

from pathlib import Path
import os

def scan_one_level(folder: str):
    base = Path(folder)
    if not base.exists():
        print(f"[bad_path] not exists: {base}")
        return
    if not base.is_dir():
        print(f"[bad_path] not dir: {base}")
        return
    # 上下文管理器自動釋放資源
    with os.scandir(base) as items:
        for item in items:
            # 禁止跟隨軟鏈接,防止死循環(huán)
            if item.is_dir(follow_symlinks=False):
                print(f"[dir ] {item.path}")
            elif item.is_file(follow_symlinks=False):
                print(f"[file] {item.path}")
            else:
                print(f"[skip] {item.path}")

scan_one_level("/data/upload")

線上坑點總結:不加follow_symlinks=False,碰到環(huán)形軟鏈接,腳本會無限遞歸,拉高磁盤IO占用,拖垮服務器。

三、自定義棧式遞歸遍歷:可控性完勝原生os.walk

原生os.walk可以實現(xiàn)遞歸遍歷,但自定義棧結構能靈活控制遍歷深度、攔截異常、按需跳過目錄,是生產(chǎn)環(huán)境首選方案。
核心設計思路:用棧保存(目錄路徑, 當前層級),循環(huán)出棧遍歷,通過max_depth限制遞歸深度,逐層捕獲權限不足、目錄已刪除、讀取失敗等所有異常,只打印錯誤日志,不終止主程序。

完整可復用生成器代碼:

from pathlib import Path
import os

def walk_files(root: str, max_depth: int = 20):
    start = Path(root).resolve()
    stack = [(start, 0)]
    while stack:
        folder, depth = stack.pop()
        # 超出設定深度直接跳過
        if depth > max_depth:
            print(f"[skip_depth] {folder}")
            continue
        try:
            with os.scandir(folder) as entries:
                for entry in entries:
                    path = Path(entry.path)
                    try:
                        # 目錄入棧實現(xiàn)遞歸,不跟隨軟鏈接
                        if entry.is_dir(follow_symlinks=False):
                            stack.append((path, depth + 1))
                            continue
                        # 文件通過yield逐個返回,惰性加載不占內(nèi)存
                        if entry.is_file(follow_symlinks=False):
                            yield path
                    except OSError as e:
                        print(f"[entry_error] path={path} err={e}")
        except PermissionError as e:
            # 無權限目錄記錄日志,繼續(xù)遍歷其他目錄
            print(f"[no_permission] path={folder} err={e}")
        except FileNotFoundError:
            # 遍歷瞬間目錄被業(yè)務刪除,常見于動態(tài)上傳目錄
            print(f"[gone] path={folder}")
        except OSError as e:
            print(f"[scan_error] path={folder} err={e}")

關鍵設計亮點

  1. yield惰性迭代:逐個產(chǎn)出文件路徑,不用一次性把全量文件存入列表,海量小文件場景避免內(nèi)存溢出,腳本意外中斷,已掃描數(shù)據(jù)已有輸出;
  2. 全鏈路異常捕獲:區(qū)分權限不足、目錄消失、讀取異常三類生產(chǎn)高頻報錯,異常僅日志記錄,不中斷全量掃描;
  3. 深度限制max_depth防止意外遍歷系統(tǒng)根目錄無限下沉,規(guī)避掃描全磁盤帶來的IO風暴。

調(diào)用示例:

for file_path in walk_files("/data/upload"):
    print(file_path)

四、基于通用遍歷器,封裝四大生產(chǎn)高頻業(yè)務腳本

依托walk_files生成器,可快速封裝超大文件排查、后綴篩選、磁盤占用統(tǒng)計、過期文件清理四類運維常用工具,所有腳本延續(xù)異常捕獲、安全校驗邏輯。

掃描超大文件:排查磁盤異常暴漲

自動篩選超過指定MB的文件,捕獲文件無法獲取大小的異常:

def find_big_files(root: str, limit_mb: int = 100):
    limit = limit_mb * 1024 * 1024
    for path in walk_files(root):
        try:
            size = path.stat().st_size
        except OSError as e:
            print(f"[stat_error] path={path} err={e}")
            continue
        if size >= limit:
            print(f"[big_file] size_mb={size / 1024 / 1024:.1f} path={path}")

find_big_files("/data/upload", 100)

按后綴過濾文件:日志、臨時文件定向篩選

統(tǒng)一小寫后綴匹配,規(guī)避大小寫后綴漏匹配問題:

def iter_by_suffix(root: str, suffixes: set[str]):
    suffixes = {s.lower() for s in suffixes}
    for path in walk_files(root):
        if path.suffix.lower() in suffixes:
            yield path

# 只遍歷.log .txt文件
for log_file in iter_by_suffix("/data/app", {".log", ".txt"}):
    print(f"[match] {log_file}")

目錄磁盤占用匯總:快速定位耗空間文件類型

按文件后綴匯總數(shù)量與占用空間,從大到小排序,排查磁盤爆滿神器:

from collections import defaultdict

def summary_folder(root: str):
    counter = defaultdict(int)
    size_map = defaultdict(int)
    for path in walk_files(root):
        suffix = path.suffix.lower() or "<no_ext>"
        try:
            size = path.stat().st_size
        except OSError as e:
            print(f"[stat_error] path={path} err={e}")
            continue
        counter[suffix] += 1
        size_map[suffix] += size
    # 按占用空間倒序輸出
    rows = sorted(size_map.items(), key=lambda x: x[1], reverse=True)
    for suffix, total_size in rows:
        print(f"{suffix:10s} count={counter[suffix]:6d} size_mb={total_size / 1024 / 1024:10.2f}")

summary_folder("/data/upload")

過期臨時文件清理:dry_run試運行杜絕誤刪

生產(chǎn)清理鐵律:先試運行、后真實刪除,通過dry_run開關控制,試運行僅打印待刪文件,確認無誤再關閉試運行執(zhí)行刪除,避免路徑傳參錯誤、邏輯bug導致批量誤刪業(yè)務文件。

import time
def delete_old_tmp(root: str, days: int = 30, dry_run: bool = True):
    now = time.time()
    expire_seconds = days * 24 * 3600
    for path in iter_by_suffix(root, {".tmp", ".bak"}):
        try:
            mtime = path.stat().st_mtime
        except OSError as e:
            print(f"[stat_error] path={path} err={e}")
            continue
        if now - mtime <= expire_seconds:
            continue
        if dry_run:
            print(f"[dry_run] delete {path}")
            continue
        try:
            path.unlink()
            print(f"[deleted] {path}")
        except OSError as e:
            print(f"[delete_error] path={path} err={e}")
# 先試運行,確認輸出無誤再改為False
delete_old_tmp("/data/upload/tmp", 30, dry_run=True)

五、線上運行避坑五條鐵律

  1. 軟鏈接必禁跟隨:所有is_dir/is_file強制follow_symlinks=False,杜絕環(huán)形軟鏈接死遞歸;
  2. 異常絕不裸奔:權限不足、文件瞬時刪除、stat獲取大小失敗全部捕獲打日志,單個目錄異常不能中斷全局掃描;
  3. 拒絕全量加載內(nèi)存:統(tǒng)一用yield惰性迭代文件,不用list一次性裝載全量路徑,適配百萬級小文件目錄;
  4. 文件刪除先演練:清理腳本默認dry_run試運行,肉眼核對待刪列表后再開啟真實刪除;
  5. 限制掃描范圍與深度:不直接從/根目錄全量掃描,限定業(yè)務目錄+最大遞歸深度,防止全盤掃描打爆磁盤IO。

結語

目錄遍歷代碼語法簡單,但適配生產(chǎn)環(huán)境的核心在于兼容各種異常場景。本地測試能用的簡易代碼,放到復雜的線上服務器大概率出錯。少追求代碼精簡優(yōu)雅,多做路徑校驗、異常捕獲、運行兜底,運維腳本才能在深夜自動巡檢時安穩(wěn)運行,減少突發(fā)故障與誤刪事故。

到此這篇關于Python中線上目錄遍歷的避坑指南的文章就介紹到這了,更多相關Python目錄遍歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

页游| 淳安县| 于田县| 岳阳市| 宝丰县| 彰化县| 北川| 延长县| 上饶县| 旬阳县| 土默特右旗| 淮滨县| 南部县| 玉龙| 晋宁县| 怀化市| 专栏| 宁远县| 荥经县| 陈巴尔虎旗| 甘洛县| 右玉县| 合川市| 宁城县| 郓城县| 西林县| 沽源县| 宁乡县| 新安县| 平南县| 安新县| 海伦市| 大连市| 淳安县| 扎鲁特旗| 昌邑市| 宁海县| 青海省| 霍邱县| 珲春市| 绿春县|