使用python模块boto3
,我再说一遍,使用boto3
,而不是boto
。如何从S3下载文件,gzip并重新上传到S3而不将文件写入磁盘?
我正在尝试编写一个AWS lambda函数,将Gzips的所有内容上传到S3。问题是lambda函数限制为512MB的磁盘空间,我的上传可能远远超过这个。
我的假设是可以使用流来做到这一点,任何帮助都将非常感谢!感谢。
[UPDATE]
以下代码有效。它会将块上传到S3,我可以看到生成的*.gz
文件。但是gzip标头没有正确添加。打开文件会导致mac Error 32 - Broken Pipe
。
有趣的是,如果文件大小小于CHUNK_SIZE
,即只有一次迭代,则文件被上传,并且没有损坏。
任何看到我做错的事情?
CHUNK_SIZE = 10000000
gz_buffer = io.BytesIO()
gz_stream = gzip.GzipFile(fileobj=gz_buffer, mode='wb', compresslevel=9)
obj = resource.Object(bucket, key)
body = obj.get()['Body']
try:
while True:
data = body.read(CHUNK_SIZE)
if data:
compressed_bytes = gz_stream.write(data)
if compressed_bytes < CHUNK_SIZE:
gz_stream.close()
cdata = gz_buffer.getvalue()[0:compressed_bytes]
# Upload cdata as multipart upload
# This is a little helper function that
# uses boto3 create_multipart_upload
multipart.upload(cdata)
else:
# Signal to S3 complete multipart upload
multipart.complete()
break
except Exception as e:
pass
答案 0 :(得分:1)
我会这样做:
import gzip,io
out_buffer = io.BytesIO()
f = gzip.open(out_buffer,"wb")
obj = resource.Object(bucket, key)
body = obj.get()['Body']
while True:
read = body.read(500000)
print('reading...')
if read:
# 1.) Stream chunks to gzip
f.seek(0)
nb_bytes = f.write(read)
# 2.) Stream compressed chunks back to S3
cdata = out_buffer.getvalue()[0:nb_bytes]
# cdata now holds the compressed chunk of data
else:
break
io.BytesIO
创建&#34;假冒&#34;内存中的文件out_buffer
不会缩小我们必须知道长度请注意,在python 2.x中,您无法将文件对象传递给gzip.open
,您必须改为创建Gzip
对象,如下所示:
f = gzip.GzipFile("foo.gz","wb",fileobj=out_buffer)