SPARK从FTP读取CSV:输入路径不存在

SPARK从FTP读取CSV:输入路径不存在,csv,apache-spark,ftp,pyspark,pyspark-sql,Csv,Apache Spark,Ftp,Pyspark,Pyspark Sql,我正在尝试做一些应该很简单的事情,但却做不到 我在FTP服务器中有一个客户提供的.csv文件。路径是这样的: ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv 通过复制和粘贴地址,我可以在浏览器(或任何其他程序)上轻松访问该文件。但我无法在pyspark上访问它 下面是我使用databricks spark csv()尝试做的事情: 我收到以下错误: org.apache.hadoop.mapred.InvalidInputException: Input

我正在尝试做一些应该很简单的事情,但却做不到

我在FTP服务器中有一个客户提供的.csv文件。路径是这样的:

ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv

通过复制和粘贴地址,我可以在浏览器(或任何其他程序)上轻松访问该文件。但我无法在pyspark上访问它

下面是我使用databricks spark csv()尝试做的事情:

我收到以下错误:

org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: ftp://[user]:[passwd]@[IP-ADDRESS]/file.csv
正在尝试将文件读取为文本文件:

df = sqlContext.read.text("ftp://[user]:[passwd]@[IP-ADDRESS]/SALES_37_TIRADENTES_2016-09-01.csv", )
df.collect()
错误:

Py4JJavaError: An error occurred while calling o147.collectToPython.
: java.io.IOException: No input paths specified in job
我很确定这与FTP访问有关,但我不确定


编辑
最后,我使用Python的
ftplib
下载了该文件并将其加载到RDD中。如果您的数据太大,这可能是一种次优的方法,但它可以工作。

您可以使用SparkFiles从FTP使用文件

添加文件(路径)

在每个节点上添加要与此Spark作业一起下载的文件。传递的路径可以是本地文件、HDFS中的文件(或其他支持Hadoop的文件系统)或HTTP、HTTPS或FTP URI

要访问Spark jobs中的文件,请使用带有文件名的L{SparkFiles.get(fileName)}查找其下载位置

>>> from pyspark import SparkFiles
>>> path = os.path.join(tempdir, "test.txt")
>>> with open(path, "w") as testFile:
...    _ = testFile.write("100")
>>> sc.addFile(path)
>>> def func(iterator):
...    with open(SparkFiles.get("test.txt")) as testFile:
...        fileVal = int(testFile.readline())
...        return [x * fileVal for x in iterator]
>>> sc.parallelize([1, 2, 3, 4]).mapPartitions(func).collect()
[100, 200, 300, 400]
以下各项经测试(pyspark-1.5.2)正常工作:

from pyspark import SparkFiles

file_path = "ftp://ftp:ftp@ftp.ed.ac.uk/pub/Unix/Win2000_PlainPassword.reg"
sc.addFile(file_path)

filename = SparkFiles.get(file_path.split('/')[-1])

rdd = sc.textFile("file://"+filename)
rdd.take(10)
rdd.collect()

下面是一些可能有用的东西(scala版本,使用spark 1.6.3测试)

首先使用Spark上下文中的wholeTextFiles方法获取文件

val dataSource = "ftp://[user]:[passwd]@[IP-ADDRESS]"

val fileRDD = sc.wholeTextFiles(dataSource).values
然后用您的选项实例化一个CsvParser

val csvParser: CsvParser = new CsvParser().withUseHeader(true).withInferSchema(true).withDelimiter(';').withCharset("cp860")
(如果不想使用标题,请不要忘记删除第一行)

最后

val df = csvParser.csvRdd(sq, fileRDD)
df.collect()

希望这有帮助

你能从任何不需要用户名/密码的网站下载示例文件吗?几乎在那里阅读
ftp.debian.org/debian/README
,运气不好
sc.addFile
将文件添加到
tmp
dir。但我仍然无法打开它,既不能使用文件名,也不能使用
SparkFiles.get(file\u name)
中的返回值,这将正确返回本地文件路径。@ArthurCamara请尝试我的更新中的建议我已经在这样做了
df.collect()
失败并出现相同错误。问题是:当打开文件并读取行时,它工作正常。指示文件实际存在。另外,值得注意的是,我运行的是Spark 1.6.2,而不是2.0(我们依赖于IBM的Bluemix)。事实上,我很抱歉,错误现在显示
java.io.FileNotFoundException:File File文件:/tmp/spark-160-ego-master/work/spark-69648973-8776-4bc4-91e9-61605c7f4d3d/userFiles-d790dfaa-b665-4afa-a08c-057d61831b8d/File.csv不存在
仍然无法在1.6.0上找到该文件。我认为这是IBM Bluemix服务器的一个问题。
val df = csvParser.csvRdd(sq, fileRDD)
df.collect()