C# 在没有OutOfMemoryException的情况下获取列表的序列化大小
好的,我只是想说清楚,我知道所有LOH的事情和进入LOH的大对象(超过85k个)和大列表(超过40k个元素) 所以我的问题是,我需要知道使用XMLSerialiser进行序列化时列表的大小(我不关心它在RAM中占用的空间或类似的东西,我只想知道序列化时列表的大小),但是如果我尝试序列化包含大元素的大列表,我会得到OutOfMemoryException(我知道为什么) 我想知道的是:是否可以逐个元素序列化一个列表,并在循环中累积它的大小,如: //这将是伪代码C# 在没有OutOfMemoryException的情况下获取列表的序列化大小,c#,serialization,stream,out-of-memory,C#,Serialization,Stream,Out Of Memory,好的,我只是想说清楚,我知道所有LOH的事情和进入LOH的大对象(超过85k个)和大列表(超过40k个元素) 所以我的问题是,我需要知道使用XMLSerialiser进行序列化时列表的大小(我不关心它在RAM中占用的空间或类似的东西,我只想知道序列化时列表的大小),但是如果我尝试序列化包含大元素的大列表,我会得到OutOfMemoryException(我知道为什么) 我想知道的是:是否可以逐个元素序列化一个列表,并在循环中累积它的大小,如: //这将是伪代码 long byteLength =
long byteLength = 0;
using(stream)
{
foreach(element in MyList)
{
MemoryStream.Serialise(element);
byteLength += MemoryStream.Length;
MemoryStream.Clear();
}
}
有什么建议吗
更新: @xanatos的解决方案做了我想做的事情,因为它没有在ram中添加一个将存储在LOH中的大字节[]
正如@Hans Passant所说,我之所以要进行这种处理,其目的似乎很重要:我想知道以XML序列化的列表的字节大小,以便能够根据其总字节将列表拆分为磁盘上的多个文件。如果您只需要长度:
class NulStream : Stream
{
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
}
protected long length;
public override long Length
{
get { return this.length; }
}
public override long Position
{
get
{
return this.length;
}
set
{
throw new NotSupportedException();
}
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
this.length += count;
}
}
using (var nul = new NulStream())
{
xml.Serialize(nul, lst);
long length = nul.Length;
}
这是一条小溪。。。就像NUL文件一样:-)它会吃你扔给它的东西,并且只保存累积长度
请注意,从技术上讲,我可以实现
SetLength
,而Write
应该检查其参数。。。但是为什么呢?:-) 是的,但似乎即使我序列化流中的对象,长度和位置似乎也没有好的值。。。我累积了MemoryStream.Length
,并使用Seek(0,0)
函数将位置重置为0。您必须非常迫切地编写这样的代码,肯定有更好的方法。从几个对象开始,通过乘以列表的计数得到一个估计值。非常不清楚您真正想要解决的问题是什么,大型序列化数据非常适合磁盘而不是内存。我认为我的问题很清楚,上下文不清楚,因为它不是必需的。我的问题是:我想序列化一个列表,而不是在LOH中序列化所有的字节。@xanatos提交的解决方案修复了它,因为它不会创建一个大的字节[]
,但只获取它的长度
。使用此方法,它不会将序列化字节存储在LOH中?因为它是原创的problem@Tareck117不,不会的。因为XmlSerializer
一次向流发送一个片段,从一些实验中得到1024-2048字节。如果您想查看它,请在覆盖void Write(…)中添加此行:Console.WriteLine(count);