我需要遍历磁盘上的大量文件列表,打开每个文件并解析它。我有一个带文件名的文件,我只需要迭代这些文件名。
我将此函数传递给 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块内的代码可以正常工作。
如何迭代指定的文件列表,提取其内容?
答案 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)