You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用PyArrow递归列出HDFS中的子文件夹与文件

递归遍历HDFS目录的PyArrow解决方案

好问题!你说得没错,PyArrow默认的fs.ls()确实只能列出指定HDFS目录下的一级对象。不过不用担心,PyArrow的HDFS连接对象提供了专门的递归遍历API——walk(),它的用法和Python标准库的os.walk()非常相似,能完美实现递归列出所有文件和子文件夹的需求。

使用walk()实现递归遍历

walk()方法会遍历指定目录及其所有子目录,每次返回一个三元组(root, dirs, files)

  • root: 当前正在遍历的目录路径
  • dirs: 当前root目录下的所有子文件夹名称列表
  • files: 当前root目录下的所有文件名称列表

你可以基于这个方法修改你的代码,获取所有层级的文件和文件夹及其元数据:

import pyarrow as pa

# 建立HDFS连接
fs = pa.hdfs.connect()
my_path = "/path/to/folder"

# 递归遍历目标目录
for root, dirs, files in fs.walk(my_path):
    # 处理子文件夹
    for dir_name in dirs:
        dir_full_path = f"{root}/{dir_name}"
        # 获取文件夹的元数据(比如最后修改时间)
        dir_meta = fs.stat(dir_full_path)
        print(f'Folder: {dir_full_path}, Last modified: {dir_meta.mtime}')
    
    # 处理文件
    for file_name in files:
        file_full_path = f"{root}/{file_name}"
        file_meta = fs.stat(file_full_path)
        print(f'File: {file_full_path}, Last modified: {file_meta.mtime}')

简化需求:仅收集所有文件路径

如果你的需求只是获取所有层级的文件路径(不需要文件夹信息),可以简化代码:

import pyarrow as pa

fs = pa.hdfs.connect()
my_path = "/path/to/folder"

all_files = []
# 遍历过程中忽略dirs,只收集files
for root, _, files in fs.walk(my_path):
    all_files.extend([f"{root}/{file}" for file in files])

# 输出所有文件路径
for file_path in all_files:
    print(file_path)

替代方案:手动递归调用ls()

如果你不想使用walk(),也可以自己实现递归逻辑,通过循环调用ls()并判断对象类型(文件夹则继续递归):

import pyarrow as pa

fs = pa.hdfs.connect()
my_path = "/path/to/folder"

def recursive_ls(path):
    obj_list = fs.ls(path, True)
    for obj in obj_list:
        print(f'{obj["name"]}, {obj["last_modified_time"]}')
        # 如果是文件夹,递归遍历
        if obj["kind"] == "directory":
            recursive_ls(obj["name"])

# 调用递归函数
recursive_ls(my_path)

不过更推荐使用官方提供的walk()方法,它的实现更高效且代码更简洁。

内容的提问来源于stack exchange,提问作者mehdi

火山引擎 最新活动