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

时间:2013-08-16 15:44:21

标签: c# serialization stream out-of-memory

好的只是要清楚,我知道所有LOH事物和大对象(超过85k)以及进入LOH的大名单(更多40k元素)。

所以我的问题是,我需要知道使用XMLSerialiser序列化时List的大小(我不关心RAM中的空间或类似的东西,我只是在序列化时想要它的大小)但如果我尝试序列化包含大元素的大列表,我会得到OutOfMemoryException (我知道为什么)

我想知道的是:是否可以序列化List Element by Element 并在循环中累积它的大小,如:     //这将是伪代码

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

    MemoryStream.Clear();
  }
}

有任何建议吗?


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

正如@Hans Passant所说,看起来为什么我想要做这个处理的目的很重要所以:我想知道在XML中序列化的List的字节大小能够在多个文件中拆分列表在磁盘上根据其总字节数。

1 个答案:

答案 0 :(得分:2)

如果您需要的只是长度:

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文件:-)它会吃你扔的东西,只保存累积长度。

请注意,从技术上讲,我可以实现SetLength,而Write应检查其参数......但为什么呢? : - )