0

好吧,为了清楚起见,我知道所有 LOH 的事情和进入 LOH 的大对象(超过 85k)和大列表(更多 40k 元素)。

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

我想知道的是:是否可以按元素序列化列表元素并在循环中累积它的大小,例如://这将是伪代码

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

    MemoryStream.Clear();
  }
}

有什么建议吗?


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

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

4

1 回答 1

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应该检查它的参数...但是为什么呢?:-)

于 2013-08-16T16:06:08.703 回答