2016-02-05 181 views
2

我有一個名爲「Source」的S3存儲桶。許多'.tgz'文件正在被實時推入該存儲區。我編寫了一個用於提取'.tgz'文件並將其推入「目標」存儲區的Java代碼。我將我的代碼推送爲Lambda函數。我在我的Java代碼中將'.tgz'文件作爲InputStream。如何在Lambda中提取它?我無法在Lambda中創建文件,它會在JAVA中引發「FileNotFound(Permission Denied)」。AWS Lambda:如何提取S3存儲桶中的tgz文件並將其放入另一個S3存儲桶中

AmazonS3 s3Client = new AmazonS3Client(); 
S3Object s3Object = s3Client.getObject(new GetObjectRequest(srcBucket, srcKey)); 
InputStream objectData = s3Object.getObjectContent(); 
File file = new File(s3Object.getKey()); 
OutputStream writer = new BufferedOutputStream(new FileOutputStream(file)); <--- It throws FileNotFound(Permission denied) here 

回答

1

不要使用FileFileOutputStream,使用s3Client.putObject()。要閱讀tgz文件,您可以使用Apache Commons Compress。例如:

ArchiveInputStream tar = new ArchiveInputStreamFactory(). 
    createArchiveInputStream("tar", new GZIPInputStream(objectData)); 
ArchiveEntry entry; 
while ((entry = tar.getNextEntry()) != null) { 
    if (!entry.isDirectory()) { 
     byte[] objectBytes = new byte[entry.getSize()]; 
     tar.read(objectBytes); 
     ObjectMetadata metadata = new ObjectMetadata(); 
     metadata.setContentLength(objectBytes.length); 
     metadata.setContentType("application/octet-stream"); 
     s3Client.putObject(destBucket, entry.getName(), 
      new ByteArrayInputStream(objectBytes), metadata); 
    } 
} 
+0

你的建議是寫回到目標桶。但我的問題是如何在lambda函數中提取tgz? – Avis

+0

AWS或lambda提取'tgz'沒有什麼特別之處。我已經使用標準Java庫和Apache Commons Compress更新了我的答案。 – ataylor

+0

這將導致文件末尾出現空值,順便說一句。 tar.read(objectBytes)將讀取緩衝區中的任何內容,但不能保證讀取整個文件,因此objectBytes最後會留下一堆空值。 – Fluffycloud

2
import boto3 
import botocore 
import tarfile 
from tarfile import TarInfo 
from botocore.client import Config 
s3_client = boto3.client('s3') 
s3_resource=boto3.resource('s3') 
def lambda_handler(event, context): 
    bucket =event['Records'][0]['s3']['bucket']['name'] 
    key = event['Records'][0]['s3']['object']['key'] 
    new_bucket='uncompressed-data' #new bucket name 
    new_key=key[:-4] 
    try: 
     s3_client.download_file(bucket, key, '/tmp/file') 
     if(tarfile.is_tarfile('/tmp/file')): 
      tar = tarfile.open('/tmp/file', "r:gz") 
      for TarInfo in tar: 
       tar.extract(TarInfo.name, path='/tmp/extract/') 
     s3_client.upload_file('/tmp/extract/'+TarInfo.name,new_bucket, new_key) 
     tar.close() 
    except Exception as e: 
     print(e) 
     raise e 

使用Python 3.6和觸發obejctcreated(全部),後綴名爲 「.tgz」 的事件。希望這可以幫助你。看看這個Link