迭代文件列表,提取其内容? (SparkContext错误)

时间:2017-02-06 17:36:15

标签: python apache-spark pyspark databricks

我需要遍历磁盘上的大量文件列表,打开每个文件并解析它。我有一个带文件名的文件,我需要迭代这些文件名。

我将此函数传递给 map()

%python

def parse(filename):
  try:
    tf = sc.textFile(filename)
    # run parsing code, produce text
    return text
  except:
      return None

当我尝试运行以下内容时:

parsed_contents = filenames.map(parse)
parsed_contents.top(5)

我收到此错误:

异常:您似乎尝试从广播变量,操作或转换中引用SparkContext。 SparkContext只能在驱动程序上使用,而不能在工作程序上运行的代码中使用。有关详细信息,请参阅SPARK-5063。

如果单独运行,指定文件名,则try块内的代码可以正常工作。

如何迭代指定的文件列表,提取其内容?

1 个答案:

答案 0 :(得分:1)

当您对rdd执行转换时(在本例中为您的调用filnames.map(parse)),驱动程序会分配工作人员来处理您的rdd的每个分区。因此,您的地图调用基本上会发送给工作人员以应用于您的rdd。在您提供的代码中,您基本上是在工作人员上运行的代码中调用sparkContext实例,这会导致错误。需要在驱动程序进程上进行文件读取。

sc.textFile接受以逗号分隔的字符串,指定要读入的文件名。 所以你可以这样做:

filenames = sc.textFile("filesToRead.txt")

parsed_contents = sc.textFile(",".join(filenames.collect()))

parsed_contents.top(5)

您还可以指定模式作为sc.textFile方法的输入。例如,

parsed_contents = sc.textFile("file[0-5].txt")

<强>更新 用于过滤磁盘上存在的文件。

def check_exists(name):
    try:
        open(name, 'r')
        True
    except:
        False

existingFiles = filenames.filter(check_exists)