web-dev-qa-db-fra.com

Pyspark: obtenir la liste des fichiers/répertoires sur le chemin HDFS

Comme dans le titre. Je suis au courant de textFile mais comme son nom l’indique, il ne fonctionne que sur les fichiers texte . Il me faudrait accéder aux fichiers/répertoires d’un chemin sur HDFS (ou chemin local). J'utilise pyspark

Merci pour l'aide

13
Federico Ponzi

Je pense qu'il est utile de penser à Spark uniquement en tant qu'outil de traitement de données, avec un domaine commençant au chargement des données. Il peut lire de nombreux formats et prend en charge les expressions globales Hadoop, qui sont terriblement utiles pour lire à partir de plusieurs chemins dans HDFS, mais il ne possède pas de fonction intégrée que je connaisse pour parcourir des répertoires ou des fichiers. utilitaires spécifiques à l’interaction avec Hadoop ou HDFS.

Il existe quelques outils disponibles pour faire ce que vous voulez, y compris esutil et hdfs . La bibliothèque hdfs supporte à la fois la CLI et l’API, vous pouvez passer directement à la section «Comment lister les fichiers HDFS en Python» à droite ici . Cela ressemble à ceci:

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

L'utilisation de la passerelle JVM n'est peut-être pas aussi élégante, mais dans certains cas, le code ci-dessous peut être utile:

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())
30
volhv

Si vous utilisez PySpark , vous pouvez exécuter les commandes de manière interactive:


Répertoriez tous les fichiers d'un répertoire choisi:

hdfs dfs -ls <path> exemple: 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

Ou recherchez des fichiers dans un répertoire choisi:

hdfs dfs -find <path> -name <expression> exemple: 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
12
Darius M.

Si vous voulez lire dans tous fichiers d'un répertoire, extrayez sc.wholeTextFiles[doc] , mais notez que le contenu du fichier est lu dans la valeur d'une seule ligne, ce qui n'est probablement pas le résultat désiré.

Si vous souhaitez lire uniquement certains fichiers, vous devez générer une liste de chemins (en utilisant une commande hdfs ls normale et le filtrage dont vous avez besoin), puis le transmettre en sqlContext.read.text[doc] , puis la conversion de DataFrame en RDD semble comme la meilleure approche.

2
Matthew Graves

Il existe un moyen facile de faire cela en utilisant la bibliothèque snakebite

from snakebite.client import Client

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

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

...     print x
0
Hgottipati