在没有OutOfMemoryException的情况下获取列表的序列化大小

本文关键字:列表 序列化 获取 情况下 OutOfMemoryException | 更新日期: 2023-09-27 18:27:55

好的,只是要明确一点,我知道所有LOH的事情,以及进入LOH的大对象(超过85k)和大列表(超过40k个元素)。

所以我的问题是,当使用XMLSerializer串行化时,我需要知道List的大小(我不在乎它在RAM或类似的东西中占用的空间,我只想要它在串行化时的大小),但如果我试图串行化包含大元素的大列表,我会得到OutOfMemoryException

我想知道的是:是否可以将List元素一个接一个地序列化,并将其大小累积在一个循环中,如://这将是伪代码

long byteLength = 0;
using(stream)
{
  foreach(element in MyList)
  {
    MemoryStream.Serialise(element);
    byteLength += MemoryStream.Length;
    MemoryStream.Clear();
  }
}

有什么建议吗?


更新:@sxanatos的解决方案做了我想做的事情,因为它没有在ram中添加将存储在LOH 中的大字节[]

正如@Hans Passant所说,我为什么要做这种处理的目的似乎很重要,所以:我想知道用XML序列化的列表的字节大小,以便能够根据其总字节将列表拆分为磁盘上的多个文件。

在没有OutOfMemoryException的情况下获取列表的序列化大小

如果您只需要长度:

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流。。。就像NUL文件:-)它会吃掉你扔给它的东西,并且只保存累积长度。

注意,从技术上讲,我本可以实现SetLengthWrite应该检查它的参数。。。但为什么?:-)