CSharp - 添加到MemoryStream之前,如何检查添加到MemoryStream的结果?

  显示原文与译文双语对照的内容
0 0

我正在使用内存流创建一个XML文件,方法如下-

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
MemoryStream ms = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(ms, settings))
{
//CREATE XML WITH STATEMENTS LIKE THIS
 writer.WriteStartElement("url", myUrl);
 writer.WriteEndElement();
}

是否有一些方法可以以检查结果 MemoryStream的长度,然后在实际添加元素之前进行检查。

有些类似-

var sizeTotal = ms + (writer.WriteStartElement("url", myUrl);

这样做的目的是检查 sizeTotal,确保在写入 MemoryStream 之前不太大。

我正在生成的XML文件的大小限制为 10MB 。 我可以以写到"临时"流 1 st,检查长度,如果 sizeTotal 小于 10 MB,写到"真实"流中的元素。 否则,如果 sizeTotal 超过 10,我想将元素添加到流中,生成XML文件,生成XML文件,然后开始新文件。

时间:原作者:7个回答

0 0

你是指这样的东西?

var myUrl ="http://www.stackoverflow.com";
var encoding = Encoding.UTF8;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = encoding;
var SOME_MAX_SIZE_IN_BYTES = 1024;
MemoryStream ms = new MemoryStream();
for(var i=0; i<10; i++)
{
 using (XmlWriter writer = XmlWriter.Create(ms, settings))
 { 
//CREATE XML WITH STATEMENTS LIKE THIS
 writer.WriteStartElement("url", myUrl);
 writer.WriteEndElement();
//in order to get a semi-accurate byte count, 
//you need to force the flush to the underlying stream
 writer.Flush();
 var lengthInBytes = ms.Length;
 if(lengthInBytes> SOME_MAX_SIZE_IN_BYTES)
 {
 Console.WriteLine("TOO BIG!");
 break;
 }
 }
}
var xml = encoding.GetString(ms.ToArray());
Console.WriteLine(xml);
原作者:
0 0

我没有办法确定一个元素在实际写它之前要多长时间。 但是你不能确定事情的时间,如果你需要的话,你可以备份。 关键是在开始写入前获取 MemoryStream的当前位置,并从写入后的位置减去该位置。 例如:

using (XmlWriter writer = XmlWriter.Create(ms, settings))
{
 long startPos = ms.Position;
//write an element
 writer.WriteStartElement("url", myUrl);
 writer.WriteEndElement();
 writer.Flush();//make sure data is flushed to the stream
 long endPos = ms.Position;
}

如果 endPos 超出了大小限制,那么可以将内存流从 0复制到 startPos,并保存它。 然后,你可以在 0处定位该流,然后重试写入。 就像这样:

using (XmlWriter writer = XmlWriter.Create(ms, settings))
{
//write an element
 while (true)
 {
 long startPos = ms.Position;
 writer.WriteStartElement("url", myUrl);
 writer.WriteEndElement();
 writer.Flush();//make sure data is flushed to the stream
 if (ms.Position <maxSize)
 break;
//here, copy memory buffer from 0 to startPos and save to disk
//then, reset position
 ms.Position = 0;
 }
//write another element
 while (true)
 {
//same thing, different element
 }
//make sure to write the final buffer!
}

这就是一般的想法。当一个单元超过阈值时,当然不要进入无限循环。

注意,我没有解决 XML Fragments的问题,这种技术无疑会创建。 如果你希望单个文件是有效的XML,则必须跟踪打开哪些元素,因这里将关闭部分文件。 你还需要在初始化下一位的内存流时打开这些元素。 你可以以为 ms.Position = 0; 做这个,也可以以在编写下一个 fragment 时做到这一点。

不了解更大的问题( 例如 。 对于这些部分文件,我不能对如何处理它做出特定的建议。

原作者:
...