Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在没有OutOfMemoryException的情况下获取列表的序列化大小_C#_Serialization_Stream_Out Of Memory - Fatal编程技术网

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

C# 在没有OutOfMemoryException的情况下获取列表的序列化大小,c#,serialization,stream,out-of-memory,C#,Serialization,Stream,Out Of Memory,好的,我只是想说清楚,我知道所有LOH的事情和进入LOH的大对象(超过85k个)和大列表(超过40k个元素) 所以我的问题是,我需要知道使用XMLSerialiser进行序列化时列表的大小(我不关心它在RAM中占用的空间或类似的东西,我只想知道序列化时列表的大小),但是如果我尝试序列化包含大元素的大列表,我会得到OutOfMemoryException(我知道为什么) 我想知道的是:是否可以逐个元素序列化一个列表,并在循环中累积它的大小,如: //这将是伪代码 long byteLength =

好的,我只是想说清楚,我知道所有LOH的事情和进入LOH的大对象(超过85k个)和大列表(超过40k个元素)

所以我的问题是,我需要知道使用XMLSerialiser进行序列化时列表的大小(我不关心它在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序列化的列表的字节大小,以便能够根据其总字节将列表拆分为磁盘上的多个文件。

如果您只需要长度:

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);