是否可以使用SparkSession对象列出给定S3路径(例如:s3://my-bucket/my-folder/*.extension)中的所有文件?
答案 0 :(得分:3)
您可以使用Hadoop API访问S3上的文件(Spark也使用它):
import java.net.URI
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.Path
import org.apache.hadoop.conf.Configuration
val path = "s3://somebucket/somefolder"
val fileSystem = FileSystem.get(URI.create(path), new Configuration())
val it = fileSystem.listFiles(new Path(path), true)
while (it.hasNext()) {
...
}
答案 1 :(得分:0)
您可以对数据帧使用Book book = entityManager
.unwrap(Session.class)
.bySimpleNaturalId(Book.class)
.load("978-9730228236");
assertEquals(
"High-Performance Java Persistence",
book.getProperties().get("title")
);
assertEquals(
"Vlad Mihalcea",
book.getProperties().get("author")
);
,它将为您提供每行的绝对文件路径。
以下代码将为您提供所有文件路径。
input_file_name
我假设。对于您的用例,您只想从带有正则表达式的一组文件中读取数据,然后将其应用于过滤器中。
例如,
spark.read.table("zen.intent_master").select(input_file_name).distinct.collect
答案 2 :(得分:0)
方法一
对于 pyspark 用户,我已经翻译了 Michael Spector 的 answer(我会留给你来决定使用它是否是一个好主意):
sc = spark.sparkContext
myPath = f's3://my-bucket/my-prefix/'
javaPath = sc._jvm.java.net.URI.create(myPath)
hadoopPath = sc._jvm.org.apache.hadoop.fs.Path(myPath)
hadoopFileSystem = sc._jvm.org.apache.hadoop.fs.FileSystem.get(javaPath, sc._jvm.org.apache.hadoop.conf.Configuration())
iterator = hadoopFileSystem.listFiles(hadoopPath, True)
s3_keys = []
while iterator.hasNext():
s3_keys.append(iterator.next().getPath().toUri().getRawPath())
s3_keys
现在保存在 my-bucket/my-prefix
方法 2 这是我发现的替代方法(hat tip 到 @forgetso):
myPath = 's3://my-bucket/my-prefix/*'
hadoopPath = sc._jvm.org.apache.hadoop.fs.Path(myPath)
hadoopFs = hadoopPath.getFileSystem(sc._jvm.org.apache.hadoop.conf.Configuration())
statuses = hadoopFs.globStatus(hadoopPath)
for status in statuses:
status.getPath().toUri().getRawPath()
# Alternatively, you can get file names only with:
# status.getPath().getName()
方法 3(不完整!)
上述两种方法不使用将应用于分布式读取的 Spark 并行机制。不过,这种逻辑看起来很私密。见parallelListLeafFiles
here。我还没有找到一种方法来强制 pyspark 对 s3 上的分布式 ls
执行操作而不读取文件内容。我尝试使用 py4j 来实例化 InMemoryFileIndex
,但无法正确使用咒语。如果有人想从这里拿起它,这是我到目前为止所拥有的:
myPath = f's3://my-bucket/my-path/'
paths = sc._gateway.new_array(sc._jvm.org.apache.hadoop.fs.Path, 1)
paths[0] = sc._jvm.org.apache.hadoop.fs.Path(myPath)
emptyHashMap = sc._jvm.java.util.HashMap()
emptyScalaMap = sc._jvm.scala.collection.JavaConversions.mapAsScalaMap(emptyMap)
# Py4J is not happy with this:
sc._jvm.org.apache.spark.sql.execution.datasources.InMemoryFileIndex(
spark._jsparkSession,
paths,
emptyScalaMap,
sc._jvm.scala.Option.empty() # Optional None
)