8

我将 XML 文件存储在 BLOB 存储中,我试图找出更新它们的最有效方法(和/或向它们添加一些元素)。在 WebRole 中,我想出了这个:

using (MemoryStream ms = new MemoryStream())
{                    
      var blob = container.GetBlobReference("file.xml");
      blob.DownloadToStream(msOriginal);
      XDocument xDoc= XDocument.Load(ms);  

      // Do some updates/inserts using LINQ to XML.  

      blob.Delete();//Details about this later on.

      using(MemoryStream msNew = new MemoryStream())  
      {
           xDoc.Save(msNew);
           msNew.Seek(0,SeekOrigin.Begin);
           blob.UploadFromStream(msNew);                    
      }                               
}

考虑到效率,我正在查看这些参数:

  1. BLOB事务
  2. 带宽。(不确定是否计算在内,因为代码在数据中心运行)
  3. 实例上的内存消耗。

有几点要提:

  • 我的 xml 文件大约 150-200 KB。

  • 我知道 XDocument 将整个文件加载到内存中,并且在流( XmlWriter 和 XmlReader )中工作可以解决这个问题。但我认为这将需要使用 BlobStream ,这可能会导致事务效率降低(我认为)。

  • 关于blob.Delete(),没有它,blob存储中上传的xml似乎在它的末尾缺少一些结束标记。我认为这是由与旧数据的冲突引起的。我在这里可能完全错了,但是使用 delete 解决了它(尽管要花费一笔交易)。

考虑到我提到的参数,我提供的代码是一种好的做法,还是存在更有效的方法?

4

2 回答 2

8

我认为基于流的方法的问题在于存储客户端在开始发送数据之前不知道流有多长时间。这可能导致内容长度未更新,从而在文件末尾出现丢失数据的外观。

以文本格式处理 blob 的内容会有所帮助。您可以将 blob 内容下载为文本,然后上传为文本。这样做,您应该能够避免删除(为您节省 1/3 的事务)并拥有更简单的代码。

var blob = container.GetBlobReference("file.xml");
var xml = blob.DownloadText(); // transaction 1
var xDoc= XDocument.Parse(xml);

// Do some updates/inserts using LINQ to XML.

blob.UploadText(xDoc.ToString()); //  transaction 2

此外,如果您可以在不下载文件的情况下重新创建文件(我们有时可以这样做),那么您可以上传它并使用一个存储事务覆盖旧文件。

var blob = container.GetBlobReference("file.xml");
var xDoc= new XDocument(/* generate file */);

blob.UploadText(xDoc.ToString()); // transaction 1
于 2012-03-14T04:53:23.810 回答
1

我知道 XDocument 将整个文件加载到内存中,并且在流( XmlWriter 和 XmlReader )中工作可以解决这个问题。

不确定它会解决太多。想想看。当它通过软管飞行时,你如何将koolaid添加到水中。这就是流。最好等到它在容器中。

除此之外,关注效率(技术问题)而不是编辑(业务问题)的原因是什么?文档的更改是否频繁到足以保证认真审视性能?还是您只是被正常的开发人员倾向于做的超出必要的事情所困扰?(注意:我也经常在这方面感到内疚)

乍一看,如果没有 Flush() 的概念,Delete 是一个可以接受的选项。我不确定转向异步方法是否可以以更少的开销促进相同的目的。

于 2011-10-04T21:07:01.880 回答