s3桶中的utf-8文件名

时间:2014-01-12 12:50:27

标签: python amazon-s3 boto

是否可以使用utf-8编码名称(例如“åøæ.jpg”)向s3添加密钥?

使用boto上传时出现以下错误:

<Error><Code>InvalidURI</Code><Message>Couldn't parse the specified URI.</Message>

2 个答案:

答案 0 :(得分:3)

@ 2083:这是一个古老的问题,但是如果你找不到解决方案,那么就像我一样来到这里寻找答案的其他人:

从官方文档(http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html):

  

虽然您可以在对象键名中使用任何UTF-8字符,但是   以下关键命名最佳实践有助于确保最大兼容性   与其他应用程序。每个应用程序都可以解析特殊   字符不同。以下指南可帮助您最大化   符合DNS,Web安全字符,XML解析器和其他API。

     

安全角色

     

以下字符集通常可以安全地用于密钥名称:

     

字母数字字符[0-9a-zA-Z]

     

特殊字符!, - ,_,。,*,&#39;,(和)

     

以下是有效对象键名称的示例:

     

4my组织

     

my.great_photos-2014 / JAN / myvacation.jpg

     

视频/ 2014 /生日/ video1.wmv

然而,如果您真正想要的是像我这样的文件名,它允许使用UTF-8字符(请注意,这可能与键名不同)。你有办法做到这一点!

http://www.bennadel.com/blog/2591-embedding-foreign-characters-in-your-content-disposition-filename-header.htmhttp://www.bennadel.com/blog/2696-overriding-content-type-and-content-disposition-headers-in-amazon-s3-pre-signed-urls.htm(Kudos到Ben Nadal),您可以确保在下载文件时,S3会覆盖 Content-Disposition 标头。

正如我在java中所做的那样,我在这里包含了代码,我确信你能够轻松地将它翻译成Python :):

      AmazonS3 s3 = S3Controller.getS3Client();

        //as per http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html

        String key = fileName.substring(fileName.indexOf("-")).replaceAll("[^a-zA-Z0-9._]", "");
        PutObjectRequest putObjectRequest = new PutObjectRequest(
                S3Controller.bucketNameForBucket(S3Controller.Bucket.EXPORT_BUCKET), 
                key,
                file);
        // we can always regenerate these files, so we can used reduced redundancy storage
        putObjectRequest.setStorageClass(StorageClass.Standard);
        String urlEncodedUTF8Filename = key;
        try {
            //http://www.bennadel.com/blog/2696-overriding-content-type-and-content-disposition-headers-in-amazon-s3-pre-signed-urls.htm
            //http://www.bennadel.com/blog/2591-embedding-foreign-characters-in-your-content-disposition-filename-header.htm
            //Issue#179
            urlEncodedUTF8Filename = URLEncoder.encode(fileName.substring(fileName.indexOf("-")), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            LOG.warn("Could not URLEncode a filename. Original Filename: " + fileName, e );
        }

        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentDisposition("attachment; filename=\"" + key + "\"; filename*=UTF-8''"+ urlEncodedUTF8Filename);
        putObjectRequest.setMetadata(metadata);

        s3.putObject(putObjectRequest);

应该有帮助:)

答案 1 :(得分:0)

来自AWS FAQ: 密钥是一系列Unicode字符,其UTF-8编码长度最多为1024字节。

根据我的经验,使用ASCII。