Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.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# 考虑流大小限制的.NET序列化_C#_.net_Serialization - Fatal编程技术网

C# 考虑流大小限制的.NET序列化

C# 考虑流大小限制的.NET序列化,c#,.net,serialization,C#,.net,Serialization,我正在序列化一个对象,它有几个子对象(也可以序列化)。我可以在序列化过程之间检查流的大小吗?(我只想限制我正在序列化的流的大小)不使用任何内置类,但您可以轻松地创建具有此限制的流包装器类 您可以这样简单地使用它: Stream limitedStream = new LimitedStream(realStream, 10 * 1024 * 1024); // 10MB max 然后序列化到该位置。根据序列化程序的不同,可以将项目独立地放到流的末尾(并且仍然可以再次读取流)。不是“纯”xml(

我正在序列化一个对象,它有几个子对象(也可以序列化)。我可以在序列化过程之间检查流的大小吗?(我只想限制我正在序列化的流的大小)

不使用任何内置类,但您可以轻松地创建具有此限制的流包装器类

您可以这样简单地使用它:

Stream limitedStream = new LimitedStream(realStream, 10 * 1024 * 1024); // 10MB max

然后序列化到该位置。

根据序列化程序的不同,可以将项目独立地放到流的末尾(并且仍然可以再次读取流)。不是“纯”xml(由于根元素),但我知道至少有一个序列化程序支持顺序对象读/写(猜测哪一个没有好处)

如果大小是绝对关键的,那么可以通过
MemoryStream
——类似(伪代码)的方式

工作完成了。这避免了通过将每个单独的对象完成到内存流中来写入部分对象(尽可能重用底层内存),因此只有在知道数据适合时才将数据复制到实际的流中

下面是一个完整的示例,使用:

使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Xml.Serialization;
使用ProtoBuf;
[XmlType]//没有实际序列化为xml;只是它需要
类MyData//一种识别成员的方法,它支持
{//通过XmlType/xmlement指定Order属性
[xmlement(Order=1)]公共int-Id{get;set;}
[XmlElement(Order=2)]公共字符串名称{get;set;}
}
静态类程序
{
静态IEnumerable GetItems()
{
Random rand=新的Random();
整数计数=0;
while(true)//数据的无限序列;mwahaahahah
{
新MyData的收益回报率
{
Id=rand.Next(0,5000),
Name=“Item”+计数++
};
}
}
静态void Main()
{
int space=2048,count=0;
长校验和=0;
使用(Stream dest=File.Create(“out.bin”))
使用(MemoryStream buffer=new MemoryStream())
{
foreach(GetItems()中的MyData对象)
{
SetLength(0);//重置为空,但保留缓冲区以减少allocs
Serializer.SerializeWithLengthPrefix(缓冲区,对象,PrefixStyle.Base128,1);
int len=(int)buffer.Length;

if(buffer.Length ok thanq.那么,如果将10mb的数据写入流,并且仍然存在要序列化的对象的某些其他属性,会发生什么情况呢?它会引发异常吗?我会编写该流类,以便在达到10mb时引发异常,是的。
using(Stream dest = ... )
using(MemoryStream buffer = new MemoryStream())
{
    foreach(SomeType obj in items) {
        buffer.SetLength(0); // reset to empty, but retaining buffer to reduce allocs
        someSerializer.Serialize(buffer, obj);

        if(enoughSpace) {
            // add our item
            dest.Write(buffer.GetBuffer(), 0, buffer.Length);
            // TODO: decrement space     
        } else {
            break; // or new file, whatever
        }
    }
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using ProtoBuf;
[XmlType]      // not actually serialized as xml; simply it needs
class MyData   // a way of identifying the members, and it supports
{              // the Order property via XmlType/XmlElement
    [XmlElement(Order = 1)] public int Id { get; set; }
    [XmlElement(Order = 2)] public string Name { get; set; }
}
static class Program
{
    static IEnumerable<MyData> GetItems()
    {
        Random rand = new Random();
        int count = 0;
        while (true) // an infinite sequence of data; mwahahaahah
        {
            yield return new MyData
            {
                Id = rand.Next(0, 5000),
                Name = "Item " + count++
            };
        }
    }
    static void Main()
    {
        int space = 2048, count = 0;
        long checksum = 0;
        using(Stream dest = File.Create("out.bin"))
        using(MemoryStream buffer = new MemoryStream())
        {
            foreach (MyData obj in GetItems())
            {
                buffer.SetLength(0); // reset to empty, but retaining buffer to reduce allocs
                Serializer.SerializeWithLengthPrefix(buffer, obj, PrefixStyle.Base128, 1);
                int len = (int)buffer.Length;
                if(buffer.Length <= space) {
                    // add our item
                    dest.Write(buffer.GetBuffer(), 0, len);
                    space -= len;
                    checksum += obj.Id;
                    count++;
                } else {
                    break; // or new file, whatever
                }
            }
        }
        Console.WriteLine("Wrote " + count + " objects; chk = " + checksum);

        using (Stream source = File.OpenRead("out.bin"))
        {
            count = 0;
            checksum = 0;
            foreach (MyData item in
                Serializer.DeserializeItems<MyData>(source, PrefixStyle.Base128, 1))
            {
                count++;
                checksum += item.Id;
            }
        }

        Console.WriteLine("Read " + count + " objects; chk = " + checksum);
    }
}