Pyspark: получить список файлов/каталогов на пути HDFS

Как в заголовке. Я знаю textFile, но, как следует из названия, он работает только в текстовом файле. Мне нужно будет получить доступ к файлам/каталогам внутри пути на HDFS (или локальном пути). Я использую pyspark

Спасибо за помощь

Ответ 1

Я считаю, что полезно думать о Spark только как о средстве обработки данных, с доменом, который начинается с загрузки данных. Он может читать множество форматов и поддерживает глобальные выражения Hadoop, которые очень полезны для чтения из нескольких путей в HDFS, но у него нет встроенного средства, которое мне известно для обхода каталогов или файлов, и при этом он не имеет утилиты, специфичные для взаимодействия с Hadoop или HDFS.

Есть несколько доступных инструментов, чтобы делать то, что вы хотите, в том числе esutil и hdfs. Библиотека hdfs поддерживает как CLI, так и API, вы можете сразу перейти к пункту "Как мне перечислить файлы HDFS в Python" прямо здесь. Это выглядит так:

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

Ответ 2

Использование шлюза 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())

Ответ 3

Если вы используете 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

Ответ 4

Если вы хотите прочитать все файлы в каталоге, проверьте sc.wholeTextFiles [doc], но обратите внимание, что содержимое файла прочитайте значение одной строки, что, вероятно, не является желаемым результатом.

Если вы хотите прочитать только некоторые файлы, затем создайте список путей (используя обычную команду hdfs ls плюс любую необходимую фильтрацию) и передайте ее в sqlContext.read.text [doc], а затем преобразование из DataFrame в RDD кажется лучшим подходом.

Ответ 5

Есть простой способ сделать это, используя библиотеку snakebite

from snakebite.client import Client

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

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

...     print x