2013-04-19 47 views
4

我寫一個應用程序,我們需要不同的S3帳戶之間傳輸文件,我們不想保存在本地文件上傳到目的地S3帳戶。
所以我們用這個獲取源文件流:從Amazon S3的帳戶文件傳送到另一個

public Stream GetFileStream(string path) 
{ 
    var pathPieces = path.Split('/'); 
    string bucket = pathPieces[0]; 
    string fileName = pathPieces[pathPieces.Length - 1]; 

    GetObjectRequest request = new GetObjectRequest(); 
    request.BucketName = bucket; 
    request.Key = fileName; 

    GetObjectResponse response = Client.GetObject(request); 

    return response.ResponseStream; 
} 

而在這之後,我們使用這個流上的目標上傳:

TransferUtility transferUtility = new TransferUtility(Client); 
    transferUtility.S3Client.PutBucket(new PutBucketRequest() { UseClientRegion = true }.WithBucketName(bucket)); 
    TransferUtilityUploadRequest request = new TransferUtilityUploadRequest() 
    .WithBucketName(bucket) 
    .WithKey(key) 
    .WithPartSize(1024) 
    .WithTimeout(100 * 60 * 60 * 1000) 
    .WithAutoCloseStream(true) 
    .WithCannedACL(S3CannedACL.PublicReadWrite) 
    .WithInputStream(fileStream) as TransferUtilityUploadRequest; 

    transferUtility.Upload(request); 

但在最後一行的「上傳」功能,調用我總是得到這個錯誤: 這個流不支持查找操作。

是否有不同的方式做什麼,我試圖做的?因爲它沒有接縫的正確方法

+0

在某種程度上充分說明,流傳輸的同時,你是無論如何下載整個文件,再重新上傳同一文件,你不保存任何帶寬在這裏,而不是讓它保存爲本地文件,然後上傳它。不必要的是要阻塞內存中的緩衝區或阻止網絡操作,這不是一個好的做法。 –

+0

我的想法是獲取一些字節[buffersize]並傳輸它們,然後獲取其他內容並傳輸它們,如果同時傳輸100 GB的文件,則我的硬盤不會滿。糾正我,如果我錯了。 –

+1

對於這樣大的文件,它無論如何都會失敗,因爲100GB的文件傳輸會有很多網絡故障,並上傳,S3首先需要的文件長度,以便它可以分爲多個部分文件,並同時上傳。因此,如果不先下載整個文件,傳輸實用程序將無法工作。 –

回答

1

亞馬遜有一個複製對象請求

AmazonS3Client client = new AmazonS3Client(); 

CopyObjectRequest request = new CopyObjectRequest { 
     SourceBucket = "fromBucket", 
     SourceKey = "fromFile", 
     DestinationBucket = "toBucket", 
     DestinationKey = "toFilename", 
     CannedACL = S3CannedACL.BucketOwnerFullControl 
}; 

CopyObjectResponse response = client.CopyObject(request); 
+0

但是這在同一個S3賬戶裏面不是2個不同的賬戶。 –

0

我真的不認爲有一種方法在帳戶之間轉移。我知道的唯一可以做到的協議是FXP。您可以向AWS提出要求,以便將來這樣做,這將是一個不錯的功能。

2

我碰到這個問題,我發佈我用來解決它的辦法。借用了Jon Skeet的一些代碼。它爲我工作,但我知道這有點笨重,可能可以改進。

string filename = "nameoffiletocopy" 

using (Stream stream = GetS3Stream(filename)) 
{ 
    AmazonS3Config config = new AmazonS3Config 
     {CommunicationProtocol = Protocol.HTTP}; 
    AmazonS3 client = 
     AWSClientFactory.CreateAmazonS3Client(
      "destinationaccesskey", 
      "destinationsecretacceskey", 
      config); 
    string destinationBucketName = "destinationbucketname"; 

    PutObjectRequest request = new PutObjectRequest 
    { 
     BucketName = destinationBucketName, 
     InputStream = stream, 
     Key = filename, 
     CannedACL = S3CannedACL.PublicRead 
    }; 

    PutObjectResponse response = client.PutObject(request);  
} 

private static Stream GetS3Stream(string filename) 
{ 
    AmazonS3Config config = new AmazonS3Config 
     {CommunicationProtocol = Protocol.HTTP}; 
    AmazonS3 client = AWSClientFactory.CreateAmazonS3Client(
     "sourceaccesskey", 
     "sourcesecretacceskey", 
     config); 
    string sourceBucketName = "sourcebucketname"; 

    GetObjectRequest request = new GetObjectRequest 
     { 
      BucketName = sourceBucketName, 
      Key = filename 
     }; 

    using (GetObjectResponse response = client.GetObject(request)) 
    { 
     byte[] binaryData = 
     ReadFully(response.ResponseStream, -1); 
     //ReadyFully from Jon Skeet's blog 
     return new MemoryStream(binaryData); 
    } 
} 

readFully方法將通過Jon Skeet