2013-10-09 35 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