2012-11-19 88 views
5

此問題的背景是基於我正在開發的虛擬文件系統。我使用的概念是不同類型存儲類型的虛擬路徑提供者,即本地文件系統,Dropbox和亞馬遜S3。我的虛擬文件的基類如下所示:使用虛擬路徑提供程序和Amazon S3 SDK上載文件

public abstract class CommonVirtualFile : VirtualFile { 
    public virtual string Url { 
     get { throw new NotImplementedException(); } 
    } 
    public virtual string LocalPath { 
     get { throw new NotImplementedException(); } 
    } 
    public override Stream Open() { 
     throw new NotImplementedException(); 
    } 
    public virtual Stream Open(FileMode fileMode) { 
     throw new NotImplementedException(); 
    } 
    protected CommonVirtualFile(string virtualPath) : base(virtualPath) { } 
} 

執行第二個Open方法是我的問題。如果我們看一下我的實現了本地文件系統,即節省了磁盤上的文件,它看起來像這樣:

public override Stream Open(FileMode fileMode) { 
    return new FileStream("The_Path_To_The_File_On_Disk"), fileMode); 
} 

如果我想保存在本地文件系統中的文件,這將是這個樣子:

const string virtualPath = "/assets/newFile.txt"; 
    var file = HostingEnvironment.VirtualPathProvider.GetFile(virtualPath) as CommonVirtualFile; 
    if (file == null) { 
     var virtualDir = VirtualPathUtility.GetDirectory(virtualPath); 
     var directory = HostingEnvironment.VirtualPathProvider.GetDirectory(virtualDir) as CommonVirtualDirectory; 
     file = directory.CreateFile(VirtualPathUtility.GetFileName(virtualPath)); 
    } 
    byte[] fileContent; 
    using (var fileStream = new FileStream(@"c:\temp\fileToCopy.txt", FileMode.Open, FileAccess.Read)) { 
     fileContent = new byte[fileStream.Length]; 
     fileStream.Read(fileContent, 0, fileContent.Length); 
    } 
    // write the content to the local file system 
    using (Stream stream = file.Open(FileMode.Create)) { 
     stream.Write(fileContent, 0, fileContent.Length); 
    } 

我想的是,如果我切換到我的Amazon S3的虛擬路徑提供我想要這個代碼直接沒有任何變化工作,以便總結的東西了,我怎麼能解決這個使用Amazon S3的SDK和如何應我在我的amazon s3虛擬路徑提供程序中實現我的Open(FileMode fileMode)方法?

+0

您應該使用[SDK](http://aws.amazon.com/sdkfornet/)。 –

+0

@AaronMcIver對不起,我的問題是模糊..我增加了更多的信息 – Marcus

+1

我認爲你需要做的是做一個接口/工廠設計,適應各種雲存儲提供商的SDK實現。請檢查您是否侵犯了他們的任何專利,例如[David Ebbo的微軟專利](http://www.google.com/patents/US20060206452) - 您試圖做的事聽起來像是一項非常酷的技術開發!祝你好運!! –

回答

1

嘿,我也代表這個問題,我解決它實現一個流。

這是我的方式,我做到了,也許它可以幫助:

public static Stream OpenStream(S3TransferUtility transferUtility, string key) 
    {      
     byte[] buffer = new byte[Buffersize + Buffersize/2]; 

     S3CopyMemoryStream s3CopyStream = 
      new S3CopyMemoryStream(key, buffer, transferUtility) 
      .WithS3CopyFileStreamEvent(CreateMultiPartS3Blob); 

     return s3CopyStream; 
    } 

我與構造流覆蓋接近和write(數組,偏移量計算)方法,並上傳流到Amazon S3部分。

public class S3CopyMemoryStream : MemoryStream 
    { 

     public S3CopyMemoryStream WithS3CopyFileStreamEvent(StartUploadS3CopyFileStreamEvent doing) 
     { 
      S3CopyMemoryStream s3CopyStream = new S3CopyMemoryStream(this._key, this._buffer, this._transferUtility); 

      s3CopyStream.StartUploadS3FileStreamEvent = new S3CopyMemoryStream.StartUploadS3CopyFileStreamEvent(CreateMultiPartS3Blob); 

      return s3CopyStream; 
     } 

     public S3CopyMemoryStream(string key, byte[] buffer, S3TransferUtility transferUtility) 
      : base(buffer) 
     { 
      if (buffer.LongLength > int.MaxValue) 
       throw new ArgumentException("The length of the buffer may not be longer than int.MaxValue", "buffer"); 

      InitiatingPart = true; 
      EndOfPart = false; 
      WriteCount = 1; 
      PartETagCollection = new List<PartETag>(); 

      _buffer = buffer; 
      _key = key; 
      _transferUtility = transferUtility; 
     } 

事件StartUploadS3FileStreamEvent調用啓動,uploadpart並完成上載的調用。

或者你可以實現一個FileStream這是容易得多,因爲你可以在被覆蓋的的FileStream的Close方法使用

TransferUtilityUploadRequest request = 
      new TransferUtilityUploadRequest() 
      .WithAutoCloseStream(false).WithBucketName(
       transferUtility.BucketName) 
       .WithKey(key) 
       .WithPartSize(stream.PartSize) 
       .WithInputStream(stream) as TransferUtilityUploadRequest; 

     transferUtility.Upload(request); 

。缺點是你必須先將整個數據寫入磁盤,然後才能上傳。

+0

對不起,對於遲到的迴應,但我很好奇關閉和寫入方法的實現如何。我已經設法上傳一個文件,但我的測試文件的內容是這樣腐敗http://cl.ly/Lbcn – Marcus

+0

你想做什麼?類:Memorystream或類:FileStream?使用Multipart API或TransferUtility界面?或者你嘗試異步上傳?你使用流還是文件路徑?也許你必須尋找流,直到開始,然後上傳? – zirbel

+1

我GOOGLE了CreateMultiPartS3Blob,發現另一個帖子http://stackoverflow.com/questions/13604916/s3-multipart-upload-exception由你和我得到了答案,設置位置爲0固定我的問題。我在你的文章中使用幾乎相同的實現,它工作正常。看起來你的代碼中有一個固定的緩衝區,或者你使用文件的大小作爲緩衝區長度?我在寫入方法中引用了這行代碼(位置> =緩衝區大小)。 – Marcus

相關問題