Python--递归与非递归遍历文件夹的方法
递归概念
递归是一种编程技术,允许函数调用自身来解决问题。设计递归函数时,需要考虑基本情况和递归步骤。
递归函数设计
- 基本情况:递归结束的条件。
- 递归步骤:函数调用自身解决更小的子问题。
递归方法实现
import os
def get_files_recursion_from_dir(path):
file_list = []
if os.path.exists(path):
for f in os.listdir(path):
new_path = os.path.join(path, f)
if os.path.isdir(new_path):
file_list += get_files_recursion_from_dir(new_path)
else:
file_list.append(new_path)
return file_list
非递归遍历方法
除了递归,以下是几种常用的遍历文件夹的方法:
1. 使用 os.walk()
os.walk()
是一个生成器函数,遍历指定目录及其子目录,生成三元组 (dirpath, dirnames, filenames)
。
import os
def get_files_walk(path):
file_list = []
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
file_list.append(os.path.join(dirpath, filename))
return file_list
2. 使用 glob.glob()
和 glob.iglob()
glob
模块提供通配符搜索文件路径的功能。
import glob
def get_files_glob(path):
file_list = []
for filename in glob.iglob(path + "/**/*", recursive=True):
file_list.append(filename)
return file_list
3. 使用 pathlib.Path
pathlib
提供面向对象的文件系统路径操作。
from pathlib import Path
def get_files_pathlib(path):
file_list = [str(file) for file in Path(path).rglob('*')]
return file_list
4. 使用 scandir()
和 scandir_iter()
scandir()
是一个迭代器,可以遍历目录中的文件和目录。
import os
def get_files_scandir(path):
file_list = []
for entry in os.scandir(path):
if entry.is_file():
file_list.append(entry.path)
elif entry.is_dir():
file_list.extend(get_files_scandir(entry.path))
return file_list
5. 使用 subprocess
通过调用系统命令,可以使用 subprocess
模块获取文件列表。
import subprocess
def get_files_subprocess(path):
result = subprocess.run(['find', path, '-type', 'f'], stdout=subprocess.PIPE)
file_list = result.stdout.decode().split('\n')
return [file for file in file_list if file]
注意事项
- 递归函数需要有明确的退出条件,避免栈溢出错误。
- 递归深度可能受到限制,对于极深的文件夹结构,递归可能不是最佳选择。
os.walk()
在遍历过程中遇到权限错误会抛出OSError
。- 遍历过程中,如果目录结构发生变化,
os.walk()
的行为是未定义的。
使用 os.access()
检查文件或目录的权限
os.access()
函数用于检查当前进程是否有权限访问指定的文件或目录。它接受以下模式作为访问权限的检查:
os.F_OK
:检查文件或目录是否存在。os.R_OK
:检查文件是否可读。os.W_OK
:检查文件是否可写。os.X_OK
:检查文件是否可执行(在UNIX系统上有效)。
使用 os.access()
检查文件或目录的权限:
- 检查文件或目录是否存在:
import os
path = '/path/to/file/or/directory'
if os.access(path, os.F_OK):
print(f"{path} 存在。")
else:
print(f"{path} 不存在。")
- 检查文件是否可读:
if os.access(path, os.R_OK):
print(f"{path} 是可读的。")
else:
print(f"{path} 不可读。")
- 检查文件是否可写:
if os.access(path, os.W_OK):
print(f"{path} 是可写的。")
else:
print(f"{path} 不可写。")
- 检查文件是否可执行(仅UNIX系统):
if os.access(path, os.X_OK):
print(f"{path} 是可执行的。")
else:
print(f"{path} 不可执行。")
- 组合检查:
if os.access(path, os.R_OK | os.W_OK):
print(f"{path} 是可读写的。")
避免 os.walk()
遍历时的权限错误
在使用 os.walk()
遍历文件夹时,可能会遇到权限错误。以下是一些避免或处理权限错误的策略:
-
检查权限:在尝试访问目录之前,使用
os.access()
函数检查当前用户是否有权限读取该目录。 -
捕获异常:在遍历过程中,使用
try-except
块来捕获可能发生的OSError
或PermissionError
异常,并决定如何处理这些异常(例如,跳过该目录或记录错误信息)。 -
使用更宽松的权限:如果程序运行在具有较少权限的用户下,考虑以更高权限运行程序,例如使用
sudo
(在Linux系统中)。 -
修改文件夹权限:在某些情况下,可能需要修改文件夹的权限,以便用户可以访问。这可以通过
os.chmod()
函数实现,但需要谨慎使用,以避免安全风险。 -
记录错误:在无法访问的目录上记录错误信息,可能对调试或了解程序运行情况有帮助。
-
用户反馈:如果程序是交互式的,可以向用户报告权限错误,并提示他们采取适当的行动。
-
使用日志:记录权限错误的详细信息到日志文件中,有助于事后分析。
-
递归检查:在递归调用
os.walk()
之前,先检查子目录的权限,如果无权限则不进行递归。 -
使用
pathlib
:虽然pathlib
的Path.rglob()
方法在遇到权限错误时也会抛出异常,但它提供了更现代的面向对象的API,可以与异常处理结合使用。
选择哪种方法取决于具体需求和个人偏好。递归是一种强大的技术,但需要谨慎使用。非递归方法如 os.walk()
和 pathlib.Path.rglob()
提供了易于理解和使用的替代方案。
原文地址:https://blog.csdn.net/mmd666/article/details/140596731
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!