【Python】遍历某目录下的所有文件夹与文件的路径、输出中文乱码问题

本文详细介绍了使用Python os模块遍历F盘下所有文件夹与文件的路径方法,包括直接调用walk函数和递归实现两种方式,并解释了编码问题及系统保留文件夹的处理。

本文与《【Java】读取其下所有文件夹与文件的路径》(点击打开链接)为姊妹篇,主要讲述Python对于文件信息的读取操作。

Python对于文件信息的读取操作,在其固有类os中。

下面以读取F盘下的所有文件夹作为例子说明这个问题:


Python对于文件夹的遍历有两种写法,一种是直接利用其封装好的walk方法直接操作。

这是Python做得比Java优势的地方:

# -*-coding:utf-8-*-
import os
for root,dirs,files in os.walk("f:\\"):
    for dir in dirs:
        print os.path.join(root,dir).decode('gbk').encode('utf-8');
    for file in files:
        print os.path.join(root,file).decode('gbk').encode('utf-8');

运行效果如下:


上述程序,将os.walk读取到的所有路径root、目录名dirs与文件名files,也就是三个文件数组利用foreach循环输出。

join方法就是讲其路径与目录名或者文件名连接起来,组成一个完整的目录。

后面的.decode('gbk').encode('utf-8');方法主要是给Eclipse下的PyDev控制台用的,如果不加控制台的输出会出现乱码,但是,如果你的Python程序是要拉到Windows的控制台cmd,使用python xx.py运行的话,请不要加这段编码方法,同时去掉开头的# -*-coding:utf-8-*-。因为cmd是使用gb2312简体中文编码的,而不是像Linux的终端是utf-8编码。

也可以根据Java的递归思想,写成以下的形式:

# -*-coding:utf-8-*-

import os;
files = list();
def DirAll(pathName):
    if os.path.exists(pathName):
        fileList = os.listdir(pathName);
        for f in fileList:
            if f=="$RECYCLE.BIN" or f=="System Volume Information":
                continue;
            f=os.path.join(pathName,f);
            if os.path.isdir(f):   
                DirAll(f);                
            else:
                dirName=os.path.dirname(f);
                baseName=os.path.basename(f);
                if dirName.endswith(os.sep):
                    files.append(dirName+baseName);
                else:
                    files.append(dirName+os.sep+baseName);


DirAll("f:\\");
for f in files:
    print f.decode('gbk').encode('utf-8');
运行效果如下:


当然,这种形式有其弊端,就是不能遍历一些系统保留文件夹,如$RECYCLE.BIN、System Volume Information等,如果不写判断条件,会导致下面的读取出错。因此,以后遍历文件夹的时候,还是建议时候上面的os.walk的方式。

不过,我们可以从上面的程序看到几个常见的用法,os.sep能够直接返回文件分隔符/或者\\、、os.path.join(文件所在目录的路径、文件名)能把文件所在目录的路径与文件名连接起来,os.path.isdir(完整路径)能判断是否是目录,endswith("xx")方法能判断字符串是否以xx结束的。os.path.dirname()能得到文件所在目录的路径,os.path.basename()能得到文件名,os.listdir(路径)能得到相应的文件列表,等等。


<think>我们被要求查找指定路径文件名为"ems_pmdata.csv"的文件路径。我们可以使用Pythonos模块或pathlib模块来遍历目录并查找匹配的文件。 思路: 1. 确定要搜索的根目录(用户可能需要指定,或者我们可以提供一个默认路径,但这里用户没有指定,所以我们需要考虑如何获取路径) 2. 由于用户没有指定路径,我们可以让用户输入,或者使用当前工作目录,或者根据需求可能需要从其他方式获取。但问题中只要求查找指定路径下,所以我们可以写一个函数,参数为要搜索的根目录。 3. 使用os.walk()遍历目录,检查每个文件是否匹配目标文件名。 4. 收集所有匹配的文件路径并返回。 注意:可能有多个同名文件同子目录中,所以我们返回一个列表。 另外,我们也可以使用pathlib,它提供了面向对象的方法,但这里我们使用os模块,因为它更通用。 步骤: 1. 导入os模块。 2. 定义一个函数,比如find_file(root_dir, filename),其中root_dir是搜索的根目录,filename是要查找的文件名。 3. 初始化一个空列表来存储匹配的文件路径。 4. 使用os.walk(root_dir)遍历目录树。 5. 对于每个目录,检查该目录下的所有文件,如果文件目标文件名相同,则将完整路径添加到列表中。 6. 返回列表。 如果找文件,返回空列表。 另外,我们也可以考虑使用glob模块,但glob模块在子目录中递归查找需要设置recursive=True,并且使用**模式,但Python版本支持可能略有同。这里我们使用os.walk更可靠。 但是,我们也可以提供两种方法,但问题要求简单明了,我们就用os.walk。 代码示例: 注意:用户要求查找的文件名是固定的"ems_pmdata.csv",所以我们将其作为参数传入,但也可以直接写死,但为了通用性,我们写成参数。 由于用户问题中只要求查找这个特定文件名,所以我们写一个函数。 另外,如果路径存在,我们应该处理异常。 我们可以在函数始时判断root_dir是否存在,如果存在则返回空列表或打印警告。 实现: 我们将编写以下函数: ```python import os def find_file(root_dir, target_filename): """ 在指定目录下递归查找目标文件,返回所有匹配的文件路径列表。 :param root_dir: 要搜索的根目录 :param target_filename: 目标文件名(包括扩展名) :return: 匹配的文件路径列表 """ matched_files = [] # 检查根目录是否存在 if not os.path.exists(root_dir): print(f"警告:路径 '{root_dir}' 存在") return matched_files # 遍历目录树 for dirpath, dirnames, filenames in os.walk(root_dir): for filename in filenames: if filename == target_filename: # 拼接完整路径 full_path = os.path.join(dirpath, filename) matched_files.append(full_path) return matched_files ``` 然后,我们可以这样调用: 比如,我们要在某个路径(比如当前目录)下查找,可以这样: ```python # 示例调用 if __name__ == '__main__': # 假设要搜索当前目录 root_directory = '.' # 当前目录 # 或者由用户输入 # root_directory = input("请输入要搜索的目录:") target_filename = "ems_pmdata.csv" results = find_file(root_directory, target_filename) if results: print("找到以下文件:") for path in results: print(path) else: print("未找到文件") ``` 注意:如果用户需要指定路径,可以在调用时传入。 但是,用户的问题中没有指定具体路径,所以我们需要用户提供或者使用默认路径。这里我们写一个示例,用户可能需要修改root_directory。 另外,如果文件系统很大,遍历可能需要时间,但这是必要的。 我们也可以考虑使用glob的递归查找,例如: ```python import glob def find_file_glob(root_dir, target_filename): # 使用glob递归查找 search_pattern = os.path.join(root_dir, '**', target_filename) # 注意:glob在递归查找时需要设置recursive=True,并且需要Python3.5以上 matched_files = glob.glob(search_pattern, recursive=True) return matched_files ``` 但是,glob在递归查找时可能会忽略隐藏目录,而且行为可能因系统而异。所以,我们还是使用os.walk更稳妥。 因此,我们主要使用os.walk版本。 现在,我们根据用户需求,我们只需要查找名为"ems_pmdata.csv"的文件。 所以,我们可以直接调用这个函数,但需要用户指定根目录,或者我们可以使用一个默认的根目录(比如当前目录)。 由于用户没有提供根目录,我们假设用户会提供或者使用当前目录。 因此,我们提供上述函数,并给出调用示例。 完整代码: 我们写一个函数,并给出调用示例(但调用示例在__main__中,用户可以直接运行,也可以在其他地方调用)。 注意:如果用户需要从命令行参数获取路径,我们可以使用argparse,但这里用户没有要求,我们就简单处理。 所以,我们这样写: 如果用户想直接运行脚本,可以输入路径,否则我们默认当前目录。 我们可以让用户通过命令行参数指定目录,或者通过输入指定。但为了简单,我们在示例中使用了当前目录。 我们可以改进,让用户通过命令行参数指定: 使用sys.argv来获取命令行参数。 例如: ```python import sys if __name__ == '__main__': if len(sys.argv) > 1: root_directory = sys.argv[1] else: root_directory = '.' target_filename = "ems_pmdata.csv" results = find_file(root_directory, target_filename) ... # 同上 ``` 这样用户可以在命令行中执行:python script.py 要搜索的路径 但是,用户的问题只是要求一个方法,所以我们提供函数和示例调用即可。 综上所述,我们提供以下代码:</think>在Python中查找指定路径下特定文件名的文件路径,可以使用`os.walk()`或`pathlib`模块递归遍历目录。以下是完整解决方案: ```python import os def find_file(root_dir, target_filename): """ 在指定目录下递归查找目标文件 :param root_dir: 要搜索的根目录路径 :param target_filename: 目标文件名(如"ems_pmdata.csv") :return: 匹配文件的完整路径列表 """ matched_files = [] for dirpath, _, filenames in os.walk(root_dir): if target_filename in filenames: full_path = os.path.join(dirpath, target_filename) matched_files.append(full_path) return matched_files # 示例用法 if __name__ == "__main__": search_directory = "/path/to/your/directory" # 替换为实际路径 target_file = "ems_pmdata.csv" results = find_file(search_directory, target_file) if results: print("找到匹配文件:") for path in results: print(f"→ {path}") else: print(f"在 {search_directory} 中未找到 {target_file}") ``` ### 关键说明: 1. **`os.walk()`原理**: - 递归遍历目录树生成三元组 `(当前路径, 子目录列表, 文件列表)` - 时间复杂度 $O(n)$(n为文件目录总数) 2. **路径处理**: - 使用 `os.path.join()` 确保跨平台路径兼容性 - 支持绝对路径和相对路径输入 3. **使用示例**: ```python # 查找当前目录下的文件 find_file(".", "ems_pmdata.csv") # 查找整个D盘 find_file("D:/", "ems_pmdata.csv") ``` ### 替代方案(使用pathlib): ```python from pathlib import Path def find_file_v2(root_dir, target_filename): return [str(p) for p in Path(root_dir).rglob(target_filename)] ``` ### 注意事项: 1. 需要文件读取权限,否则会跳过受保护目录 2. 网络路径可能需要额外处理(如 `r"\\server\share"`) 3. 大目录搜索时考虑性能优化: ```python # 添加提前终止条件(找到第一个匹配项即返回) if stop_at_first_match and matched_files: return matched_files ``` ### 相关问题 1. 如何递归删除特定扩展名的文件? 2. 怎样监控文件夹中新创建的文件? 3. 如何处理文件名编码问题(如中文乱码)? 4. 如何获取文件的创建/修改时间属性? > 引用说明:文件路径处理参考了系统路径规范[^2],递归遍历算法基于标准库实现[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值