Alf*_*lfe 12 python gzip amazon-s3 boto gzipfile
我有一个大的本地文件.我想使用该boto库将该文件的gzip压缩版本上传到S3 .该文件太大,无法在上载之前在磁盘上高效地进行gzip,因此在上传过程中应该以流式方式对其进行gzip压缩.
该boto库知道一个函数set_contents_from_file(),它需要一个类似文件的对象.
该gzip库知道GzipFile可以通过名为的参数获取对象的类fileobj; 它会在压缩时写入此对象.
我想结合这两个函数,但是一个API想要自己阅读,另一个API想要自己编写; 既不知道被动操作(如写入或被读取).
有没有人知道如何以工作方式结合这些?
编辑:我接受了一个答案(见下文),因为它暗示我要去哪里,但如果你有同样的问题,你可能会发现我自己的答案(也在下面)更有帮助,因为我实现了一个使用分段上传的解决方案.
Alf*_*lfe 24
我在garnaat接受的答案的评论中实施了暗示的解决方案:
import cStringIO
import gzip
def sendFileGz(bucket, key, fileName, suffix='.gz'):
key += suffix
mpu = bucket.initiate_multipart_upload(key)
stream = cStringIO.StringIO()
compressor = gzip.GzipFile(fileobj=stream, mode='w')
def uploadPart(partCount=[0]):
partCount[0] += 1
stream.seek(0)
mpu.upload_part_from_file(stream, partCount[0])
stream.seek(0)
stream.truncate()
with file(fileName) as inputFile:
while True: # until EOF
chunk = inputFile.read(8192)
if not chunk: # EOF?
compressor.close()
uploadPart()
mpu.complete_upload()
break
compressor.write(chunk)
if stream.tell() > 10<<20: # min size for multipart upload is 5242880
uploadPart()
Run Code Online (Sandbox Code Playgroud)
它似乎没有问题.毕竟,流媒体在大多数情况下只是数据的分块.在这种情况下,大块大约10MB,但谁在乎呢?只要我们不是在谈论几个GB块,我对此很好.
Python 3的更新:
from io import BytesIO
import gzip
def sendFileGz(bucket, key, fileName, suffix='.gz'):
key += suffix
mpu = bucket.initiate_multipart_upload(key)
stream = BytesIO()
compressor = gzip.GzipFile(fileobj=stream, mode='w')
def uploadPart(partCount=[0]):
partCount[0] += 1
stream.seek(0)
mpu.upload_part_from_file(stream, partCount[0])
stream.seek(0)
stream.truncate()
with open(fileName, "rb") as inputFile:
while True: # until EOF
chunk = inputFile.read(8192)
if not chunk: # EOF?
compressor.close()
uploadPart()
mpu.complete_upload()
break
compressor.write(chunk)
if stream.tell() > 10<<20: # min size for multipart upload is 5242880
uploadPart()
Run Code Online (Sandbox Code Playgroud)
您还可以使用 gzip 轻松压缩字节并轻松上传如下:
import gzip
import boto3
cred = boto3.Session().get_credentials()
s3client = boto3.client('s3',
aws_access_key_id=cred.access_key,
aws_secret_access_key=cred.secret_key,
aws_session_token=cred.token
)
bucketname = 'my-bucket-name'
key = 'filename.gz'
s_in = b"Lots of content here"
gzip_object = gzip.compress(s_in)
s3client.put_object(Bucket=bucket, Body=gzip_object, Key=key)
Run Code Online (Sandbox Code Playgroud)
可以s_in用任何字节、io.BytesIO、pickle dumps、文件等替换。
如果你想上传压缩的 Json 那么这里是一个很好的例子:Upload compression Json to S3
实际上没有办法做到这一点,因为S3不支持真正的流输入(即分块传输编码).您必须在上传之前知道Content-Length,并且知道这是首先执行gzip操作的唯一方法.
| 归档时间: |
|
| 查看次数: |
7440 次 |
| 最近记录: |