【发布时间】:2011-07-15 06:07:55
【问题描述】:
我正在使用 XmlDictionaryWriter 将对象序列化到带有数据协定序列化程序的数据库中。 效果很好,大小和速度都比使用 text/xml 好 2 倍。
但是,我将不得不处理我的数据库中的大量记录,其中任何额外的字节都会直接转换为数据库大小的千兆字节。 这就是为什么我想通过使用 XML 字典来进一步减小大小。
我该怎么做?
我看到 XmlDictionaryWriter.CreateBinaryWriter 静态方法接受 IXmlDictionary 类型的第二个参数。 MSDN 说“用作共享字典的 XmlDictionary”。
首先我尝试使用系统提供的实现:
XmlDictionary dict = new XmlDictionary();
string[] dictEntries = new string[]
{
"http://schemas.datacontract.org/2004/07/MyContracts",
"http://www.w3.org/2001/XMLSchema-instance",
"MyElementName1",
"MyElementName2",
"MyElementName3",
};
foreach ( string s in dictEntries )
dict.Add( s );
结果是 .NET 框架完全忽略了字典,仍然将上述字符串作为纯文本插入,而不是仅仅引用相应的字典条目。
然后我创建了自己的 IXmlDictionary 实现:
class MyDictionary : IXmlDictionary
{
Dictionary<int, string> values = new Dictionary<int, string>();
Dictionary<string, int> keys = new Dictionary<string, int>();
MyDictionary()
{
string[] dictEntries = new string[]
{
"http://schemas.datacontract.org/2004/07/MyContracts",
"http://www.w3.org/2001/XMLSchema-instance",
"MyElementName1",
"MyElementName2",
"MyElementName3",
};
foreach ( var s in dictEntries )
this.Add( s );
}
static IXmlDictionary s_instance = new MyDictionary();
public static IXmlDictionary instance { get { return s_instance; } }
void Add( string val )
{
if ( keys.ContainsKey( val ) )
return;
int id = values.Count + 1;
values.Add( id, val );
keys.Add( val, id );
}
bool IXmlDictionary.TryLookup( XmlDictionaryString value, out XmlDictionaryString result )
{
if ( value.Dictionary == this )
{
result = value;
return true;
}
return this.TryLookup( value.Value, out result );
}
bool IXmlDictionary.TryLookup( int key, out XmlDictionaryString result )
{
string res;
if ( !values.TryGetValue( key, out res ) )
{
result = null;
return false;
}
result = new XmlDictionaryString( this, res, key );
return true;
}
public bool /* IXmlDictionary. */ TryLookup( string value, out XmlDictionaryString result )
{
int key;
if ( !keys.TryGetValue( value, out key ) )
{
result = null;
return false;
}
result = new XmlDictionaryString( this, value, key );
return true;
}
}
结果是 - 我的 TryLookup 方法调用正常,但是 DataContractSerializer.WriteObject 生成一个空文档。
如何使用预共享字典?
提前致谢!
附:我不想弄乱 XmlBinaryReaderSession/XmlBinaryWriterSession:我没有“会话”,而是有一个 10 GB 以上的数据库,可以同时被多个线程访问。我想要的只是静态预定义字典。
更新:好的,我发现我只需要调用“XmlDictionaryWriter.Flush”。剩下的唯一问题是 - 为什么系统提供的 IXmlDictionary 实现没有按预期工作?
【问题讨论】:
标签: c# .net .net-4.0 c#-4.0 datacontractserializer