2015-12-04 185 views
1

在文件名中具有冒号的亚马逊S3文件我有一个S3存储桶,其中包含在其文件名中含冒号的多个文件。加载通过pyspark

实施例:

s3://my_bucket/my_data/en/2015120/batch:222:111:00000.jl.gz 

我试图如下到火花RDD加载此并访问第一行。

my_data = sc.textFile("s3://my_bucket/my_data/en/2015120/batch:222:111:00000.jl.gz") 
my_data.take(1) 

但这抛出,

llegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: 

任何建议,以单独或更优选加载这些文件的整个文件夹

+0

可以尝试使用*在文件名中。像's3://path/*.gz'。我正在使用和上面一样的东西,它正在为我工​​作。 – dheee

回答

0

请注意,为了访问S3,你需要使用s3n架构,而不仅仅是s3,如Spark FAQ中所述,否则Hadoop解析器fails。此

0

一种解决方案是使用自定义的文件系统实现,因为他们没有here (Totango Labs)

它的要点是,你绕过内部globStatus功能,它试图解释文件名的路径,而不是使用listStatus 。不足之处在于,虽然这可以让您使用带冒号的S3网址,但它不会允许您在网址中指定通配符。

final Configuration hadoopConf = sparkContext.hadoopConfiguration(); 
hadoopConf.set("fs." + CustomS3FileSystem.SCHEMA + ".impl", 
    CustomS3FileSystem.class.getName()); 

public class CustomS3FileSystem extends NativeS3FileSystem { 
    public static final String SCHEMA = "custom"; 

    @Override 
    public FileStatus[] globStatus(final Path pathPattern, final PathFilter filter) 
     throws IOException { 
    final FileStatus[] statusList = super.listStatus(pathPattern); 
    final List<FileStatus> result = Lists.newLinkedList(); 
    for (FileStatus fileStatus : statusList) { 
     if (filter.accept(fileStatus.getPath())) { 
     result.add(fileStatus); 
     } 
    } 
    return result.toArray(new FileStatus[] {}); 
    } 
} 
0

我知道它的工作原理是将冒号替换为url编码格式。

:将与%3A

要仔细检查更换,请单击S3的对象之一,看到 “链接”

S3 Screenshot