zoukankan      html  css  js  c++  java
  • Python 设置S3文件属性中元数据的Content-Encoding值

    背景: 使用脚本从S3下载下来的CSV文件打开发现是乱码,但是在网页上面点击下载按钮下载后却能正常打开.

    研究发现,在S3文件属性的元数据中有Content-Encoding值是gzip

    浏览器下载的时候会识别这个值,然后在帮你自动减压后下载. 但是利用官方boto3包的download_fileobj()方法中,却无法指定对应的参数(不知道以后不会优化).

    下载的话就比较简单了,下载后直接利用gzip解压后再处理数据即可.

    import boto3
    import gzip
    import csv
    
    
    s3 = boto3.client('s3')
    bucket = 'my_bucket'
    download_key = 'my.csv'
    file_path = '/tmp/my.csv'
    
    with open('/tmp/my.csv.gz', 'wb') as file_date:
        s3.download_fileobj(bucket, download_key, file_date)
    g = gzip.GzipFile(mode="rb", fileobj=open('/tmp/my.csv.gz', 'rb'))
    open(file_path, "wb").write(g.read())
    csv_file_open = open(file_path, 'r')
    csv_file = csv.reader(csv_file_open)
    
    

    上传的我研究了好久.因为我发现upload_file()方法中也无法提供Content-Encoding参数,虽然我找到了ExtraArgs参数中可以添加Metadata的字段,然后发现这个是个自定义元数据用的.会自动转换成x-amz-meta-content-encoding.这就很扯淡了.

    s3_resource.meta.client.upload_file(file_path, bucket, key, ExtraArgs={'Metadata': {'Content-Encoding': 'gzip'}})
    

    进一步研究发现在copy_object()方法中ContentEncoding 参数才是真正用来设置S3文件属性的元数据中的Content-Encoding值.

    所以有一种方法是先用uploadfile上传数据,然后在用copy_object()拷贝后修改Content-Encoding属性.(这样比较蛋疼)

    最后发现put_object()方法也带有这个参数,这样的话我们可以利用put_object方法来操作.代码片段如下.自己先压缩好gzip文件.

    f = open('/tmp/my_gz.csv', 'rb')
    response = s3.put_object(Body=f, Bucket=bucket,  Key='my.csv', ContentEncoding='gzip')
    
  • 相关阅读:
    C#微信公众号的开发——服务配置
    JavaJDBC整理
    JavaSet接口、唯一元素和Map接口整理
    Java泛型、List接口整理
    Java集合、Iterator迭代器和增强for循环整理
    Java基础内部类、包的声名、访问修饰符、代码块整理
    Java基础super关键字、final关键字、static关键字、匿名对象整理
    Java基础构造方法和this关键字整理
    Java抽象类、接口整理
    Java封装、继承整理
  • 原文地址:https://www.cnblogs.com/crazyzero/p/11727628.html
Copyright © 2011-2022 走看看