2

根据我们的系统所在的环境,它将使用不同的“文件系统”来管理用户上传的文件。例如,在我们的开发环境中,我们使用 Windows 文件系统,但在生产环境中,我们使用 Azure Blob 存储。

使用提供者模型,我创建了以下接口:

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 服务器上的某个虚拟目录中一样。 出于这个原因,我决定完全使用流。 由客户端代码根据需要处理流。

问题:

  • 会更好FileStream还是MemoryStream更好?
  • 将文件公开为字节数组是否有好处?
  • 你能看出这种方法有什么严重的缺点吗?
4

1 回答 1

4

无论您使用 FileStream 还是 MemoryStream 或其他一些流类型,都无关紧要。您的界面应该只接受一个 Stream,然后可以处理各种不同的输入。

我会说流比字节数组更灵活。不过,需要注意的一件事是,在将流传递给接口之前,您通常必须记住在流上设置 position=0。

您还应该考虑异步以及是否要处理正确的流式传输 - 即在仍从客户端接收数据的同时写入 Azure blob 存储(这对于 azure 存储 API 的工作方式可能有点棘手)。

我要说的一件事是,您的界面看起来像是在尝试使 Azure Blob 存储的行为类似于文件系统,并强调文件名。Azure blob 存储对文件的名称有一定的限制;本质上,您的“名称”需要进行 URI 编码。我发现更好的方法是接受 Azure blob 存储有效地处理标识符的想法,然后尝试在文件系统上模拟它。因此,当您“保存”一个文件时,您将传入一个名称和一个流,并将返回一个作为标识符的字符串(它实际上是一个 URI 或 URI 的一部分)。客户端必须存储该标识符,并且在他们想要检索文件时必须提供该标识符。

这样做的另一个好处是您的实现负责生成标识符,因此可以在标识符中包含一个 Guid 以避免任何名称冲突。

最后,如果您计划在 Azure Blob 存储中存储大量文件,您应该知道浏览速度很慢,而且几乎无法搜索。因此,为了使支持更容易,请仔细考虑如何构建标识符。虽然从技术上讲 Blob 存储是扁平的,但您可以通过在标识符中包含“/”来模拟文件夹结构。因此,例如,您可以创建一个标识符,如年 + “/” + 月 + “/” + 日 + “/” + guid + '/' + Uri.Encode(filename)。或者您可以在标识符中包含一些特定于上下文的信息。

于 2013-10-09T22:13:56.490 回答