2013-10-09 65 views
1

根據我們系統託管的環境,它將使用不同的「文件系統」來管理用戶上傳的文件。例如,在我們的開發環境中,我們使用Windows文件系統,但在生產中我們使用Azure blob存儲。IFileRepositoryProvider處理上傳的文件

使用提供程序模型,我創建了以下接口:

public interface IFileRepositoryProvider 
{ 
    void SaveFile(string fileName, Stream fileStream); 

    void DeleteFile(string fileName); 

    bool Exists(string fileName); 

    Stream GetStream(string fileName); 
} 
  • 的文件是如何保存/刪除/等細節完全由IFileRepositoryProvider具體實現封裝。
  • Azure blob存儲有一些限制。我不一定會爲文件提供一個直接的「URI」,就像我們可以將它放在Web服務器上的某個虛擬目錄中一樣。 因此,我決定完全使用流。根據需要由客戶端代碼來處理流。

問題:

  • FileStreamMemoryStream更好嗎?
  • 將文件暴露爲字節數組有什麼好處嗎?
  • 你能看到這種方法的嚴重缺點嗎?
+1

在Windows Azure中運行時,BLOB將存儲在公共容器還是私有? – MikeWo

+0

私人容器。 – davenewza

回答

3

不管你使用FileStream或MemoryStream還是其他一些流類型都沒關係;您的界面應該只接受一個Stream,然後可以處理各種不同的輸入。

我會說流比字節數組更靈活。但要注意的一點是,在將流傳遞給接口之前,您通常必須記住在您的流上設置position = 0。

您還應該考慮異步問題以及是否要處理正確的流 - 即在寫入Azure blob存儲的同時仍然從客戶端接收數據(這對於azure存儲API的工作方式可能有點棘手)。

我要說的一件事就是你的界面看起來像你試圖讓Azure blob存儲的行爲像文件系統一樣,重點在於文件名。 Azure blob存儲中有關於可以調用文件的某些限制;實質上,你的「名字」需要被URI編碼。我發現更好的方法是接受Azure blob存儲有效地脫離標識符,然後嘗試在文件系統上模擬它的想法。所以,當你'保存'一個文件時,你會傳入一個名字和一個流,並且會返回一個字符串,它是一個標識符(它實際上是一個URI或URI的一部分)。客戶端必須存儲該標識符,並且當他們想要檢索文件時必須呈現該標識符。

這樣做的另一個好處是您的實現負責生成標識符,因此可以在標識符中包含Guid以避免任何名稱衝突。

最後,如果您計劃在Azure Blob存儲中存儲大量文件,則應該意識到瀏覽速度慢並且幾乎不可能進行搜索。因此,爲了讓支持更容易,請仔細考慮如何構建標識符。雖然技術上Blob存儲是平坦的,但您可以通過在標識符中包含「/」來模擬文件夾結構。因此,例如,您可以創建一個標識符,如year +「/」+ month +「/」+ day +「/」+ guid +'/'+ Uri.Encode(filename)。 或者您可以在標識符中包含一些特定於上下文的信息。

+0

Windows Azure存儲客戶端庫中有一個方法用於檢查blob是否存在。 http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloudblockblob.exists.aspx –

+0

@Mike啊,我的壞。感謝您指出。答案已更新。 – Frans