2012-11-19 10 views
5

この質問の背景は、私が開発している仮想ファイルシステムに基づいています。私が使用しているコンセプトは、さまざまなタイプのストレージタイプ、つまりローカルファイルシステム、ドロップボックス、およびamazon s3のvirutalパスプロバイダです。仮想ファイルの基本クラスは次のようになります。仮想パスプロバイダと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) { } 
} 

2番目の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のMicrosoft Patents](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; 
    } 

私の流れは近いと書き込み(配列、オフセット、カウント)メソッドをオーバーライドし、一部を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は、アップロードを開始し、アップロードを完了し、アップロードを完了する呼び出しを呼び出します。

また、あなたがオーバーライドのFileStreamのcloseメソッドで

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

     transferUtility.Upload(request); 

を使用することができますので、はるかに簡単であるのFileStreamを実装することができます。欠点は、最初にディスク全体にデータを書き込んでからアップロードする必要があることです。

+0

遅い応答に申し訳ありませんが、私はクローズドメソッドと書き込みメソッドの実装がどのようになっているのか不思議です。私はファイルをアップロードすることができましたが、テストファイルの内容がこのように壊れています。http://cl.ly/Lbcn – Marcus

+0

何をしようとしていますか?クラス:Memorystreamまたはクラス:FileStream? Multipart APIまたはTransferUtilityインターフェイスの使用または、非同期にアップロードしようとしていますか?ストリームまたはファイルパスを使用していますか?多分あなたは最初までストリームを探してアップロードする必要がありますか? – zirbel

+1

私はCreateMultiPartS3BlobをGoogleで検索し、別の投稿http://stackoverflow.com/questions/13604916/s3-multi-part-upload-exceptionを見つけました。私はそこに答えを得ました。位置を0に設定すると問題が解決しました。あなたの投稿とほぼ同じ実装を使用していますが、うまくいきます。あなたのコードに固定バッファがあるか、バッファ長としてファイルのサイズを使用しているようですか?私は、このコード行をwriteメソッドで(Position> = Buffersize)と参照します。 – Marcus

関連する問題