Hadoop Pyspark:获取HDFS路径上的文件/目录列表

Hadoop Pyspark:获取HDFS路径上的文件/目录列表,hadoop,apache-spark,pyspark,Hadoop,Apache Spark,Pyspark,按照标题。我知道textFile,但顾名思义,它只对文本文件有效。 我需要访问HDFS或本地路径上路径内的文件/目录。我使用的是pyspark。如果您想读入目录中的所有文件,请查看sc.wholeTextFiles,但请注意,该文件的内容被读入一行的值中,这可能不是期望的结果 如果只想读取一些文件,则生成路径列表(使用普通的hdfs ls命令加上所需的任何筛选)将其传递到sqlContext.read.text中,然后从DataFrame转换为RDD似乎是最好的方法。我认为将Spark仅仅看作一

按照标题。我知道
textFile
,但顾名思义,它只对文本文件有效。 我需要访问HDFS或本地路径上路径内的文件/目录。我使用的是pyspark。

如果您想读入目录中的所有文件,请查看
sc.wholeTextFiles
,但请注意,该文件的内容被读入一行的值中,这可能不是期望的结果


如果只想读取一些文件,则生成路径列表(使用普通的hdfs ls命令加上所需的任何筛选)将其传递到
sqlContext.read.text
中,然后从
DataFrame
转换为
RDD
似乎是最好的方法。

我认为将Spark仅仅看作一个数据处理工具是有帮助的,它的域从加载数据开始。它可以读取多种格式,并且支持Hadoop glob表达式,这对于读取HDFS中的多个路径非常有用,但它没有我所知的用于遍历目录或文件的内置工具,也没有特定于与Hadoop或HDFS交互的实用工具

有一些可用的工具可以做您想做的事情,包括和。hdfs库支持CLI和API,您可以直接跳到“如何在Python中列出hdfs文件”右侧。看起来是这样的:

从hdfs导入配置
client=Config()
files=client.list(“目录路径”)

使用JVM网关可能不是那么优雅,但在某些情况下,下面的代码可能会有所帮助:

URI=sc.\u gateway.jvm.java.net.URI
Path=sc.\u gateway.jvm.org.apache.hadoop.fs.Path
FileSystem=sc.\u gateway.jvm.org.apache.hadoop.fs.FileSystem
Configuration=sc.\u gateway.jvm.org.apache.hadoop.conf.Configuration
fs=FileSystem.get(URI(“hdfs://somehost:8020“”,配置())
status=fs.listStatus(路径('/some\u dir/还有另一个\u one\u dir/'))
对于处于状态的文件状态:
打印(fileStatus.getPath())
如果使用,可以交互执行命令:


列出所选目录中的所有文件:

hdfs-fs-ls
例如:
hdfs-ls/user/path

导入操作系统
导入子流程
cmd='hdfs dfs-ls/user/path'
files=subprocess.check_输出(cmd,shell=True).strip().split('\n')
对于文件中的路径:
打印路径

或在选定目录中搜索文件:

hdfs-dfs-find-name
例如:
hdfs-find/user/path-name*.txt

导入操作系统
导入子流程
cmd='hdfs dfs-find{}-name*.txt'。格式(source_dir)
files=subprocess.check_输出(cmd,shell=True).strip().split('\n')
对于文件中的路径:
filename=path.split(os.path.sep)[-1]。split('.txt')[0]
打印路径、文件名

使用snakebite库有一种简单的方法可以做到这一点

来自snakebite.client导入客户端
hadoop_client=client(hadoop_主机,hadoop_端口,use_trash=False)
对于hadoop_client.ls(['/'])中的x:
...     打印x

这可能适合您:

import subprocess, re
def listdir(path):
    files = str(subprocess.check_output('hdfs dfs -ls ' + path, shell=True))
    return [re.search(' (/.+)', i).group(1) for i in str(files).split("\\n") if re.search(' (/.+)', i)]

listdir('/user/')
这也起到了作用:

hadoop = sc._jvm.org.apache.hadoop
fs = hadoop.fs.FileSystem
conf = hadoop.conf.Configuration()
path = hadoop.fs.Path('/user/')
[str(f.getPath()) for f in fs.get(conf).listStatus(path)]

如果要筛选结果,请使用
globStatus
而不是
fileStatus
,例如
status=fs.globStatus(路径('/some_dir/但另一个_one_dir/*.csv'))
这很好,因为它不需要我上传额外的库到spark-submit。谢谢你的回答。在pyspark中获取/查找
某个主机(即namenode)的好方法是什么?我有数千个文件,而这段代码
文件=[file.getPath()for file in status]
需要一段时间。这正常吗?我想说这不是最有效的方法。嗨,文件=子进程。检查输出(cmd\u find)。strip()。拆分('\n')是文件=子进程。检查输出(cmd)。strip()。拆分('\n')我试过编辑,但我说编辑必须大于6个更改。@Darius Morawiec:如何执行
hdfs-rm-r
命令?它是使用相同的check_输出方法还是其他方法?@Shankar,您可以使用或。嗨,请您指导我如何制作hdfscli.cfg文件,我不知道要将其放入哪个端口号。[global]default.alias=dev[dev.alias]url=user=ann2nd@ShivamKotwalia因为我不能指定一个用户访问我的EMR,它必须是完全动态的,我不会通过我的代码传递配置的用户我支持在get_client('dev')中输入什么,我没有别名“dev”@hahaattpro您可以调用该函数而无需参数,仅当设置了备用别名时才需要此选项。如果不确定,请查找文件~/.hdfscli.cfg,并在其中搜索
default.alias