0

在我的程序中,我希望保存用户可能拥有的对象列表。每个对象都有一个特定的值,很像 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 = 位置值

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

第二个注意事项: 这种方法,没有控制字符,只会给我<60个可能的对象ID/参考号。我认为使用 Unicode 可能会更好,因为它可以支持更多字符,给我更大的范围。使用我当前的代码,有没有办法在 ASCII 上使用 Unicode?如果这是一个非常基本的问题,我提前道歉,因为我对 Stack 还很陌生...

4

4 回答 4

2

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

于 2013-05-01T22:18:47.553 回答
1

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

然后使用 Convert.ToBase64String(byte_array) ,您将拥有一个可以在 XML 文档中安全使用的字符串。

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

于 2013-05-02T02:21:22.710 回答
0

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

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

于 2013-05-02T17:59:53.227 回答
0

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

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

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

于 2013-05-01T22:33:06.833 回答