当我在pyspark收集它们时,为什么我的`binaryFiles`为空?

时间:2016-07-07 23:06:36

标签: python hadoop zip pyspark binaryfiles

我在同一个文件夹中的hdfs上有两个zip文件:/user/path-to-folder-with-zips/

我将其传递给"二进制文件"在pyspark:

zips = sc.binaryFiles('/user/path-to-folder-with-zips/')

我试图解压缩zip文件并对其中的文本文件执行操作,因此我尝试查看当我尝试处理RDD时的内容。我是这样做的:

zips_collected = zips.collect()

但是,当我这样做时,它会给出一个空列表:

>> zips_collected
[]

我知道拉链不是空的 - 它们有文本文件。文档here

每个文件都作为单个记录读取,并以键值对的形式返回,其中键是每个文件的路径,值是每个文件的内容。

我在这里做错了什么?我知道我无法查看文件的内容,因为它是压缩的,因此是二进制的。但是,我至少应该能够看到 SOMETHING 。为什么不返回任何东西?

每个zip文件可以有多个文件,但内容总是这样:

rownum|data|data|data|data|data
rownum|data|data|data|data|data
rownum|data|data|data|data|data

1 个答案:

答案 0 :(得分:1)

我假设每个zip文件包含一个文本文件(代码很容易更改为多个文本文件)。在逐行处理之前,您需要首先通过io.BytesIO读取zip文件的内容。解决方案基于https://stackoverflow.com/a/36511190/234233

import io
import gzip

def zip_extract(x):
    """Extract *.gz file in memory for Spark"""
    file_obj = gzip.GzipFile(fileobj=io.BytesIO(x[1]), mode="r")
    return file_obj.read()

zip_data = sc.binaryFiles('/user/path-to-folder-with-zips/*.zip')
results = zip_data.map(zip_extract) \
                  .flatMap(lambda zip_file: zip_file.split("\n")) \
                  .map(lambda line: parse_line(line))
                  .collect()