使用Python脚本从HDFS(Hadoop分布式文件系统)目录获取文件列表

5
如何使用Python脚本从HDFS(Hadoop)目录中获取文件列表?
我已经尝试了以下代码行:
dir = sc.textFile("hdfs://127.0.0.1:1900/directory").collect()
该目录包含文件列表:"file1,file2,file3...fileN"。使用该行可以获取所有内容的列表,但我需要获取文件名列表。
请问有人能帮我解决这个问题吗?
提前感谢您的帮助。
6个回答

9

使用子进程

import subprocess
p = subprocess.Popen("hdfs dfs -ls <HDFS Location> |  awk '{print $8}'",
    shell=True,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT)

for line in p.stdout.readlines():
    print line

编辑:请不要使用Python。第一个选项也可以用于递归打印所有子目录。最后的重定向语句可以根据您的需求省略或更改。

hdfs dfs -ls -R <HDFS LOCATION> | awk '{print $8}' > output.txt
hdfs dfs -ls <HDFS LOCATION> | awk '{print $8}' > output.txt

编辑: 修正了awk命令中缺少的引号。


2
import subprocess

path = "/data"
args = "hdfs dfs -ls "+path+" | awk '{print $8}'"
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

s_output, s_err = proc.communicate()
all_dart_dirs = s_output.split() #stores list of files and sub-directories in 'path'

这看起来像是对这个答案的改进。你可能想要[编辑]你的答案来解释这些改进。 - Adrian W

1

为什么不使用-C标志让HDFS客户端处理较难的工作,而不是依赖awk或python来打印感兴趣的特定列?

例如:Popen(['hdfs', 'dfs', '-ls', '-C', dirname])

然后,在新行上分割输出,就可以得到路径列表。

这里有一个示例,包括记录和错误处理(包括目录/文件不存在时的处理):

from subprocess import Popen, PIPE
import logging
logger = logging.getLogger(__name__)

FAILED_TO_LIST_DIRECTORY_MSG = 'No such file or directory'

class HdfsException(Exception):
    pass

def hdfs_ls(dirname):
    """Returns list of HDFS directory entries."""
    logger.info('Listing HDFS directory ' + dirname)
    proc = Popen(['hdfs', 'dfs', '-ls', '-C', dirname], stdout=PIPE, stderr=PIPE)
    (out, err) = proc.communicate()
    if out:
        logger.debug('stdout:\n' + out)
    if proc.returncode != 0:
        errmsg = 'Failed to list HDFS directory "' + dirname + '", return code ' + str(proc.returncode)
        logger.error(errmsg)
        logger.error(err)
        if not FAILED_TO_LIST_DIRECTORY_MSG in err:
            raise HdfsException(errmsg)
        return []
    elif err:
        logger.debug('stderr:\n' + err)
    return out.splitlines()

0
请使用以下内容:
hdfsdir = r"hdfs://VPS-DATA1:9000/dir/"
filepaths = [ line.rsplit(None,1)[-1] for line in sh.hdfs('dfs','-ls',hdfsdir).split('\n') if len(line.rsplit(None,1))][1:]

for path in filepaths:
    print(path)

0

获取目录中HDFS文件列表:

hdfsdir = /path/to/hdfs/directory
    filelist = [ line.rsplit(None,1)[-1] for line in sh.hdfs('dfs','-ls',hdfsdir).split('\n') if len(line.rsplit(None,1))][1:]
    for path in filelist:
        #reading data file from HDFS 
        with hdfs.open(path, "r") as read_file:
            #do what u wanna do
            data = json.load(read_file)

这个列表是HDFS目录中所有文件的列表

filelist = [ line.rsplit(None,1)[-1] for line in sh.hdfs('dfs','-ls',hdfsdir).split('\n') if len(line.rsplit(None,1))][1:]

0

针对Python 3:

    from subprocess import Popen, PIPE
hdfs_path = '/path/to/the/designated/folder'
process = Popen(f'hdfs dfs -ls -h {hdfs_path}', shell=True, stdout=PIPE, stderr=PIPE)
std_out, std_err = process.communicate()
list_of_file_names = [fn.split(' ')[-1].split('/')[-1] for fn in std_out.decode().readlines()[1:]][:-1]
list_of_file_names_with_full_address = [fn.split(' ')[-1] for fn in std_out.decode().readlines()[1:]][:-1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接