Как в заголовке. Я знаю textFile, но, как следует из названия, он работает только в текстовом файле. Мне нужно будет получить доступ к файлам/каталогам внутри пути на HDFS (или локальном пути). Я использую pyspark
Спасибо за помощь
Как в заголовке. Я знаю textFile, но, как следует из названия, он работает только в текстовом файле. Мне нужно будет получить доступ к файлам/каталогам внутри пути на HDFS (или локальном пути). Я использую pyspark
Спасибо за помощь
Я считаю, что полезно думать о 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')
Использование шлюза 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())
Если вы используете 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
Если вы хотите прочитать все файлы в каталоге, проверьте sc.wholeTextFiles
[doc], но обратите внимание, что содержимое файла прочитайте значение одной строки, что, вероятно, не является желаемым результатом.
Если вы хотите прочитать только некоторые файлы, затем создайте список путей (используя обычную команду hdfs ls плюс любую необходимую фильтрацию) и передайте ее в sqlContext.read.text
[doc], а затем преобразование из DataFrame
в RDD
кажется лучшим подходом.
Есть простой способ сделать это, используя библиотеку snakebite
from snakebite.client import Client
hadoop_client = Client(HADOOP_HOST, HADOOP_PORT, use_trash=False)
for x in hadoop_client.ls(['/']):
... print x