【问题标题】:Append to CloudBlockBlob stream附加到 CloudBlockBlob 流
【发布时间】:2017-12-11 13:39:04
【问题描述】:

我们有一个文件系统抽象,允许我们在本地和云 (Azure) 存储之间轻松切换。

对于读写文件,我们有以下成员:

Stream OpenRead();
Stream OpenWrite();

我们的应用程序的一部分将文档“捆绑”到一个文件中。对于我们的本地存储提供者OpenWrite 返回一个可附加流:

public Stream OpenWrite()
{
    return new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, BufferSize, useAsync: true);
}

对于 Azure blob 存储,我们执行以下操作:

public Stream OpenWrite()
{               
    return blob.OpenWrite();
}

不幸的是,这每次都会覆盖 blob 内容。是否可以返回一个可以追加的可写流?

【问题讨论】:

    标签: azure azure-storage azure-blob-storage


    【解决方案1】:

    基于OpenWrite 此处http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloudblockblob.openwrite.aspxThe OpenWrite method will overwrite an existing blob unless explicitly prevented using the accessCondition parameter. 的文档

    您可以做的一件事是读取流中的 blob 数据并将该流返回给调用应用程序,然后让该应用程序将数据附加到该流中。例如,看下面的代码:

        static void BlobStreamTest()
        {
            storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
            CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference("temp");
            container.CreateIfNotExists();
            CloudBlockBlob blob = container.GetBlockBlobReference("test.txt");
            blob.UploadFromStream(new MemoryStream());//Let's just create an empty blob for the sake of demonstration.
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        blob.DownloadToStream(ms);//Read blob data in a stream.
                        byte[] dataToWrite = Encoding.UTF8.GetBytes("This is line # " + (i + 1) + "\r\n");
                        ms.Write(dataToWrite, 0, dataToWrite.Length);
                        ms.Position = 0;
                        blob.UploadFromStream(ms);
                    }
                }
                catch (StorageException excep)
                {
                    if (excep.RequestInformation.HttpStatusCode != 404)
                    {
                        throw;
                    }
                }
            }
        }
    

    【讨论】:

    • 这就是我最终要做的。推荐的方法似乎是 CloudBlockBlob.PutBlock,但我们依靠 PDF 库来执行我们的“捆绑”,它只能用于单个输入流。
    • CloudBlockBlob.PutBlock 是推荐的,因为如果文件变大,那么上面的方法不会有效,因为你要下载整个 blob 并再次上传。使用PutBlock,您只需上传附加部分。
    • 是的,这是每次替换 blob 的一大缺点。但是,如前所述,我们受到 PDF 库的限制。如果这成为问题,我们可能会考虑缓存 blob 的本地副本。
    • 链接到 MSDN 由于 Microsoft 结构更改而中断
    【解决方案2】:

    现在有一个 CloudAppendBlob 类允许您向现有 blob 添加内容:

    var account = CloudStorageAccount.Parse("storage account connectionstring");
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference("container name");
    var blob = container.GetAppendBlobReference("blob name");
    

    在您的情况下,您想从流中追加:

    await blob.AppendFromStreamAsync(new MemoryStream());
    

    但您可以从文本、字节数组、文件追加。检查文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      • 2012-08-04
      • 2018-09-14
      相关资源
      最近更新 更多