Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services S3/Cloudfront:如何列出文件夹&x27;桶里的东西_Amazon Web Services_Amazon S3_Salesforce_Apex - Fatal编程技术网

Amazon web services S3/Cloudfront:如何列出文件夹&x27;桶里的东西

Amazon web services S3/Cloudfront:如何列出文件夹&x27;桶里的东西,amazon-web-services,amazon-s3,salesforce,apex,Amazon Web Services,Amazon S3,Salesforce,Apex,我编写了一个方法,对URL进行签名以读取通过Cloudfront访问的S3存储桶: private HTTPResponse signURL(String endpoint) { String keyPairId = 'keyPairId'; String secret = 'SOME_SECRET'; String method = 'GET'; Datetime dt = Datetime.now(); Long l

我编写了一个方法,对URL进行签名以读取通过Cloudfront访问的S3存储桶:

private HTTPResponse signURL(String endpoint) {
    String keyPairId = 'keyPairId';
    String secret    = 'SOME_SECRET';
    String method    = 'GET';
    Datetime dt      = Datetime.now();
    Long l           = dt.getTime();
    Long expiryLong  = (l / 1000) + 3600;
    String expiry    = String.valueOf(expiryLong);
    String policy    = policy('http://' + cfhost + '/' + endpoint, expiry);
    String policyEnc = EncodingUtil.base64Encode(Blob.valueOf(policy));
    String rPolicy   = cfReplace(policyEnc);
    Blob mac         = Crypto.generateMac('HMACSHA1',
                                          Blob.valueOf(rPolicy),
                                          Blob.valueOf(secret));
    String signature = cfReplace(EncodingUtil.base64Encode(mac));

    HttpRequest req = new HttpRequest();
    req.setMethod(method);
    req.setEndpoint('http://' + cfhost + '/' + endpoint + '?Policy=' +
        policyEnc + '&Signature=' + signature + '&Key-Pair-Id=' +
        keyPairId);

    Http http = new Http();
    HTTPResponse res = http.send(req);
    return res;
}
现在,如果端点设置为
'
,则我的方法可以正常工作。如果我把文件夹名放在端点中(比如
00q1700008lrcaew/*
),我会在XML响应中得到一堆错误

XMLNode[ELEMENT,Error,null,null,null,[XMLNode[ELEMENT,Code,null,null,null,[XMLNode[TEXT,null,null,null,null,null,NoSuchKey,]],null,], XMLNode[ELEMENT,Message,null,null,null,[XMLNode[TEXT,null,null,null,null,null,The specified key does not exist.,]],null,], XMLNode[ELEMENT,Key,null,null,null,[XMLNode[TEXT,null,null,null,null,null,00Q17000008LRcAEAW/*,]],null,], XMLNode[ELEMENT,RequestId,null,null,null,[XMLNode[TEXT,null,null,null,null,null,some_req_id,]],null,], XMLNode[ELEMENT,HostId,null,null,null,[XMLNode[TEXT,null,null,null,null,null,some_host_id,]],null,]],null,]

我不能列出整个桶,因为它对于1000键的限制太大了。如何列出文件夹?

有关列表对象以及S3期望的内容,请参阅S3文档

简而言之,您必须在查询字符串中提供前缀和分隔符(几乎总是
/
),而不是路径。对于对象列表,路径始终是存储桶的根,例如:

https://dxxxexample.cloudfront.net/?delimiter=/&prefix=00Q17000008LRcAEAW/&...
这也意味着,如果您为发行版定义了一个目录列表,那么您也不能通过发行版获取目录列表。您需要第二个发行版,或者在这种情况下,您需要直接从S3获取对象列表


无论如何,请记住,对象列表相对昂贵,超过了
GET
请求价格的10倍,因此如果缓存响应是有意义的,那么使用CloudFront获取它们可能是有意义的,或者您可能希望对对象列表执行完全不同的操作。我已经推出了一个使用S3事件通知、Lambda和RDS的设置,将所有对象及其元数据存储在一个单独的近实时数据库中,在那里我可以获得更快、更完整的列表,而无需支付任何费用(并且我可以根据对象的元数据搜索对象).

单引号不适用于Java中的字符串。我强烈建议使用jets3t,而不是手工编写所有这些内容。是的,我的平台上没有单引号。感谢您提供的深入信息!这很有帮助。