2017-03-10 5 views
1

boto3を使用して、boto3を使用して、botoを再度使用してみましょう。 S3からファイルをダウンロードし、gzipしてS3に再アップロードするにはどうすればファイルがディスクに書き込まれますか?Boto3 gzipをダウンロードしてストリームとしてアップロード

S3にアップロードされたすべてのコンテンツをGzipsするAWSラムダ関数を記述しようとしています。問題はラムダ関数が512MBのディスクスペースに制限されていることで、アップロードがこれをはるかに超えている可能性があります。

私の前提として、ストリームを使用してこれを行うことができます。どんな助けでも大歓迎です!ありがとう。

[更新日]

以下のコードが動作します。チャンクをS3にアップロードすると、*.gzファイルが表示されます。しかし、gzipヘッダーは正しく追加されていません。ファイルを開くと、MAC Error 32 - Broken Pipeになります。興味深いことに、ファイルサイズがCHUNK_SIZEより小さい場合、すなわち反復が1回だけである場合、ファイルはアップロードされ、壊れていない。

私は間違っていますか?

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

は 'io.BytesIO'を使用します。私はあなたのコードなしでもっと説明することはできません。 –

+0

基本的なコードに感謝しました。 – chasez0r

+0

今質問は良いです。 –

答えて

0

私はこれだろう。

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 
  • (あなたのコードを読むためにループ
  • その上にgzipでハンドルをマップ
  • メモリに "偽" ファイルを作成するために使用io.BytesIOを)
  • 書き込み前に偽のファイルハンドルを開始しようとするので、あまりメモリを使用しません(現在の書き込みは前のiを上書きします)。は、gzipハンドルにデータを読み書きします(書き込まれるバイト数をメモします(データによって異なります)。前回の反復よりも短い場合、out_bufferは短縮されません。
  • この長さを使用してバッファの内容をスライスして圧縮チャンクを作成します。
+0

ありがとうございます。しかし、f = gzip.open(out_buffer、 "wb")の結果、TypeErrorが発生します。Unicodeへの強制:必要な文字列またはバッファ、_io.StringIOが見つかりました。どんな考え?私は、Lambdaが制限しているものとしてPython 2.7を使用していることに注意してください。 – chasez0r

関連する問題