我正在使用XmlDictionaryWriter將對象序列化爲數據與數據約定序列化程序的數據庫。 它效果很好,尺寸和速度都比使用text/xml好2倍。使用預共享字典的.NET二進制XML
但是,我將不得不在數據庫中處理大量的記錄,其中任何額外的字節都會直接轉換爲數據庫大小的千兆字節。 這就是爲什麼我希望通過使用XML字典進一步縮小尺寸的原因。
我該怎麼做?
我看到XmlDictionaryWriter.CreateBinaryWriter靜態方法接受類型爲IXmlDictionary的2-nd參數。 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方法被稱爲OK,但是DataContractSerializer.WriteObject產生一個空文件。
如何使用預共享字典?
在此先感謝!
P.S.我不想弄亂XmlBinaryReaderSession/XmlBinaryWriterSession:我沒有「會話」,而是一次有很多線程訪問10 GB +數據庫。我想要的只是靜態預定義字典。
更新:好吧我已經想通了,我只需要調用「XmlDictionaryWriter.Flush」。剩下的唯一問題是 - 爲什麼系統提供的IXmlDictionary實現不按預期工作?