gpt4 book ai didi

c# - 要序列化的属性有大小限制吗?

转载 作者:行者123 更新时间:2023-12-01 19:42:12 29 4
gpt4 key购买 nike

我正在处理一个需要 XML 文档的界面。到目前为止,我已经能够使用 XmlSerializer 序列化大多数对象。然而,有一个属性被证明是有问题的。它应该是包装文档的对象的集合。文档本身被编码为 base64 字符串。

基本结构是这样的:

//snipped out of a parent object
public List<Document> DocumentCollection { get; set; }
//end snip

public class Document
{
public string DocumentTitle { get; set; }
public Code DocumentCategory { get; set; }
/// <summary>
/// Base64 encoded file
/// </summary>
public string BinaryDocument { get; set; }
public string DocumentTypeText { get; set; }
}

问题是较小的值可以正常工作,但如果文档太大,序列化程序只会跳过集合中的该文档项。

我遇到了一些限制吗?

更新:我改变了

public string BinaryDocument { get; set; }

public byte[] BinaryDocument { get; set; }

我仍然得到相同的结果。较小的文档(~150kb)可以很好地序列化,但其余的则不然。需要明确的是,这不仅仅是属性的值,而是整个包含的 Document 对象被删除。

更新2:

这是带有简单重现的序列化代码。它是我整理的一个控制台项目的一部分。问题是这段代码在测试项目中运行良好。我很难将完整的对象结构打包到这里,因为由于填充字段的复杂性,几乎不可能在测试用例中使用实际对象,因此我尝试减少主应用程序中的代码。填充的对象进入序列化代码,其中 DocumentCollection 填充了四个文档,并生成一个文档。

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var container = new DocumentContainer();
var docs = new List<Document>();
foreach (var f in Directory.GetFiles(@"E:\Software Projects\DA\Test Documents"))
{
var fileStream = new MemoryStream(File.ReadAllBytes(f));
var doc = new Document
{
BinaryDocument = fileStream.ToArray(),
DocumentTitle = Path.GetFileName(f)
};

docs.Add(doc);
}

container.DocumentCollection = docs;

var serializer = new XmlSerializer(typeof(DocumentContainer));
var ms = new MemoryStream();
var writer = XmlWriter.Create(ms);

serializer.Serialize(writer, container);
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);

var reader = new StreamReader(ms, Encoding.UTF8);
File.WriteAllText(@"C:\temp\testexport.xml", reader.ReadToEnd());
}
}

public class Document
{
public string DocumentTitle { get; set; }
public byte[] BinaryDocument { get; set; }
}

// test class
public class DocumentContainer
{
public List<Document> DocumentCollection { get; set; }
}
}

最佳答案

XmlSerializer 对可序列化的字符串长度没有限制。

.Net 然而,有一个 maximum string length of int.MaxValue 。此外,由于字符串在内部被实现为连续的内存缓冲区,因此在 32 位进程上,由于进程空间 fragmentation,您可能无法在任何接近那么大的位置分配字符串。 。而且,由于 C# base64 字符串大约需要创建它的 byte [] 数组内存的 2.67 倍( 1.33 for the encoding 乘 2,因为 .Net char 类型是实际上是两个字节)您可能会得到一个 OutOfMemoryException 将大型二进制文档编码为完整的 base64 字符串,然后吞下并忽略它,留下 BinaryDocument 属性 null.

话虽如此,您没有理由手动将二进制文档编码为 base64,因为 XmlSerializer 会自动为您完成此操作。 IE。如果我序列化以下类:

public class Document
{
public string DocumentTitle { get; set; }
public Code DocumentCategory { get; set; }
public byte [] BinaryDocument { get; set; }
public string DocumentTypeText { get; set; }
}

我得到以下 XML:

<Document>
<DocumentTitle>my title</DocumentTitle>
<DocumentCategory>Default</DocumentCategory>
<BinaryDocument>AAECAwQFBgcICQoLDA0ODxAREhM=</BinaryDocument>
<DocumentTypeText>document text type</DocumentTypeText>
</Document>

如您所见,BinaryDocument 采用 base64 编码。因此,您应该能够以更紧凑的 byte [] 表示形式保存二进制文档,并且仍然获得您想要的 XML 输出。

更好的是,XmlWriter 在幕后使用 System.Xml.Base64Encoder去做这个。此类将其输入编码为 block ,从而避免了上述的过度内存使用和潜在的内存不足异常。

关于c# - 要序列化的属性有大小限制吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36271086/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com