【问题标题】:Serialization of Control characters控制字符的序列化
【发布时间】:2013-04-25 23:45:05
【问题描述】:

在我的程序中,我希望保存用户可能拥有的对象列表。每个对象都有一个特定的值,很像 ID 或引用。我认为将对象的数值转换为 ASCII 字符以保存到磁盘是一个好主意。

这是我的对象数组:

public short[,] Data = new short[5,5];

我用随机数(42 到 100 之间,代表用户可能拥有的对象 ID)填充它,然后将数据转换为 ASCII 字符,然后再将其序列化为文件:

for (int i = 0; i <= 4; i++)
{
    for (int ii = 0; ii <= 4; ii++)
    {
        Data[i, ii] = (short)Rand.Next(42, 100); //random numbers to get random characters
        Save_Data.ASCII += (char)Data[i, ii]; //Converting to ASCII and adding to Class which will be saved to file
    }
}

XmlSerializer Writer = new XmlSerializer(typeof(Save_Data)); 

using (FileStream file = File.OpenWrite(myfile)) 
{
    Writer.Serialize(file, Save_Data);
}

读取文件时,我没有收到任何错误,并且可以将数据转换回值列表。 虽然原始数据在一个数组中,但我没有包含将列表重新放入数组的代码

Save_Data fList; 

XmlSerializer Reader = new XmlSerializer(typeof(Save_Data)); 

using (FileStream input = File.OpenRead(myfile)) 
{
    fList = Reader.Deserialize(input) as Save_Data; //Reading in the data
}

string Final = "";

byte[] ASCII = Encoding.ASCII.GetBytes(fList.World);

foreach (Byte b in ASCII)
{
    Final += " " + b.ToString();
}

Console.WriteLine(Final);

这很好用。 但是,如果我扩展随机函数的范围,即:

Rand.Next(12,100);

要包含其他 ASCII 字符,例如控制字符,在将文件读取到我的程序时出现错误:

XML 文档 (x, y) 中存在错误。

(x = 行,Y = 列)

它后来指出异常是:

"'V',十六进制值W,为无效字符。行X,位置 Y.

V = ASCII 控制字符

W = 此控制字符的十六进制值

X = 行号

Y = 位置值

控制字符是否不可序列化?如果是这样,有没有办法解决这个问题?

第二个注意事项:这种方法没有控制字符,只会给我

【问题讨论】:

  • michaelb958 的回答是正确的。我也非常强烈地鼓励您探索更多关于 XML 的基本原理,特别是如何很好地使用它。这不仅仅是文本转储:标签应该自我描述数据,因此人类有一些机会“读取” XML 文件的含义。以这种方式转储对象数组根本不是自我描述的。

标签: c# unicode xml-serialization ascii


【解决方案1】:

here 所述,大多数 ASCII 控制字符在将 raw 嵌入 XML 文档时都是无效的。使用&amp;#DECIMAL;&amp;#xHEX; 对它们进行实体转义是包含这些字符的首选方式。

【讨论】:

  • 使用字符引用获取控制字符仅适用于 XML 1.1,许多工具无法读取。而且你仍然无法获得 nul 字符。
【解决方案2】:

另一种方法是根据短数组的尺寸创建一个字节数组,并用 (byte)Data[i, ii] 填充它。

然后使用 Convert.ToBase64String(byte_array),您将获得一个可以安全地用于 XML 文档的字符串。

对于反序列化,使用 Covert.FromBase64String(xml_value) 取回字节数组,并循环填充您的短数组。

【讨论】:

  • 如何将字符转换为字节?一个char是16bits,一个byte只有8个?
  • 是的,但是使用的字符(因为你这么说)总是在 ascii 范围内,换句话说,在字节值范围内。
  • 哦,好的。我只是在使用您建议将它们转换为 char 的示例,但这不起作用。不过还是谢谢。
  • 哎呀。我的错。我将 (char)Data[i, ii] 更改为 (byte)Data[i, ii]。它应该工作。很抱歉。
  • 谢谢。正是我想要的。认为它实际上是 Convert.FromBase64String(xml_value) 但无论如何,谢谢!
【解决方案3】:

问题在于您将二进制数据嵌入到文本文档中。要么在二进制序列化中完成全部工作,要么通过.ToString() 方法将您的数字转换为字符串。

如果您将对象数组更改为一维数组,那么您可以简单地将您的string Save_Data.ASCII 替换为short[] Save_Data.DataXmlSerializer 将直接对其进行序列化,而无需您手动将任何内容转换为字符串。这是 IMO 最简单的事情。

WRT unicode,与原来的问题相同,它仍然是嵌入到文本中的二进制文件。因此,如果您的字符之一是例如'&lt;',XML 将认为它是新标签的开始,现在您的 XML 无效,无论是否为 unicode。我的第 2 段中的解决方案完全避免了这个问题,因为 int 在序列化之前被编码为十进制字符串。

【讨论】:

    【解决方案4】:

    您是否尝试直接序列化数组?

    我认为您没有太多理由尝试为它完成 XML 序列化程序的工作。您应该做的最糟糕的事情是将您的 5x5 数组展平为 25 个元素的一维数组。

    【讨论】:

    • 不能序列化二维数组。
    猜你喜欢
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2015-05-03
    • 2012-05-24
    • 1970-01-01
    相关资源
    最近更新 更多