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

时间:2016-03-02 14:53:13

标签: hadoop apache-spark pyspark

如标题所示。我'我知道textFile但顾名思义,它只适用于文本文件。 我需要访问HDFS(或本地路径)上的路径内的文件/目录。我正在使用pyspark

感谢您的帮助

6 个答案:

答案 0 :(得分:33)

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

URI           = sc._gateway.jvm.java.net.URI
Path          = sc._gateway.jvm.org.apache.hadoop.fs.Path
FileSystem    = sc._gateway.jvm.org.apache.hadoop.fs.FileSystem
Configuration = sc._gateway.jvm.org.apache.hadoop.conf.Configuration


fs = FileSystem.get(URI("hdfs://somehost:8020"), Configuration())

status = fs.listStatus(Path('/some_dir/yet_another_one_dir/'))

for fileStatus in status:
    print(fileStatus.getPath())

答案 1 :(得分:14)

如果您使用PySpark,则可以交互式执行命令

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

hdfs dfs -ls <path>例如:hdfs dfs -ls /user/path

import os
import subprocess

cmd = 'hdfs dfs -ls /user/path'
files = subprocess.check_output(cmd, shell=True).strip().split('\n')
for path in files:
  print path

或搜索所选目录中的文件:

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

import os
import subprocess

cmd = 'hdfs dfs -find {} -name *.txt'.format(source_dir)
files = subprocess.check_output(cmd, shell=True).strip().split('\n')
for path in files:
  filename = path.split(os.path.sep)[-1].split('.txt')[0]
  print path, filename

答案 2 :(得分:12)

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

有一些可用的工具可以执行您想要的操作,包括esutilhdfs。 hdfs lib支持CLI和API,您可以直接跳转到“我如何在Python中列出HDFS文件”右here。它看起来像这样:

from hdfs import Config
client = Config().get_client('dev')
files = client.list('the_dir_path')

答案 3 :(得分:3)

如果您要阅读目录中的所有文件,请查看sc.wholeTextFiles [doc],但请注意文件的内容会被读入值单行,这可能不是理想的结果。

如果您只想读取一些文件,那么生成一个路径列表(使用普通的hdfs ls命令加上您需要的任何过滤)并将其传递到sqlContext.read.text [doc]然后转换为DataFrameRDD似乎是最好的方法。

答案 4 :(得分:1)

这可能对您有用:

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)]

答案 5 :(得分:0)

使用snakebite库

可以轻松实现此目的
from snakebite.client import Client

hadoop_client = Client(HADOOP_HOST, HADOOP_PORT, use_trash=False)

for x in hadoop_client.ls(['/']):

...     print x