我将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);
}
}
考虑到效率,我正在研究这些参数:
有些事要提及:
我的xml文件大约为150-200 KB。
我知道XDocument将整个文件加载到 内存,以及在流中工作(XmlWriter和XmlReader)可以 解决这个问题但我认为这将需要使用BlobStream 这可能导致交易效率降低(我认为)。
关于blob.Delete(),没有它,blob存储中上传的xml 似乎在它的末尾缺少一些结束标签。我以为 这是由与旧数据的冲突引起的。我可以是 这里完全错了,但使用删除解决了它(花费一个 更多交易虽然)。
考虑到我提到的参数,我提供的代码是一个好的做法还是更有效的方法?
答案 0 :(得分:5)
我认为基于流的方法存在的问题是存储客户端在开始发送数据之前不知道流的长度。这可能导致内容长度无法更新,从而导致文件末尾缺少数据。
以文本格式处理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
答案 1 :(得分:1)
我知道XDocument将整个文件加载到内存中,并且在流中工作(XmlWriter和XmlReader)可以解决这个问题。
不确定它会解决太多问题。想一想。如何在飞过软管的过程中向水中添加koolaid。这就是流。最好等到它放在容器中。
除此之外,关注效率(技术问题)而不是编辑(业务问题)的原因是什么?文件是否经常更改以保证认真审视绩效?或者你只是成为正常的开发者倾向于做更多的事情而不是必要的东西? (注意:我在这方面也经常有罪)
如果没有Flush()的概念,乍一看删除是一个可接受的选项。我不确定转向asynch方法是否可以以更少的开销促进同一目的。