c#中, List序列化和反序列化的问题, 有一些细节不是很清楚, 请大神解答

coder1988 2013-08-02 04:48:11
我现在在做一个把记录加密存储进.dat文件的模块, 每条记录大概是时间+操作的格式, 采用的加密并存放文件的代码来自http://blog.csdn.net/paiooo/article/details/7017211, 现在我要加密的对象里面有一个list就是用于存放时间的字符串的, 整个代码大致如下

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;

namespace Console_CS
{
class Program
{
public static void Main()
{
CGameGlobal g = new CGameGlobal();

//读取记录, 第一次读取文件时需要暂时注释掉, 因为还没有生成记录文件
g = CObjFileStore.LoadObj("Global.dat") as CGameGlobal;

//只在第一次执行时添加记录, 执行第一遍以后就应该注释起来
g.lstSdcsData.Clear();
for (int i = 0; i < 5000; i++)
{
string strNow = DateTime.Now.ToString();
g.lstSdcsData.Add(strNow);
}

//输出记录
for (int i = 0; i < 5000; i++)
{
Console.WriteLine(g.lstSdcsData[i] + "\t" + i);
}
//保存记录
CObjFileStore.SaveObj("Global.dat", g);
}
}


}

/// <summary>
/// 记录类
/// </summary>
[System.Serializable]
public class CGameGlobal
{
public List<string> lstSdcsData = new List<string>();
}


/// <summary>
///
/// </summary>
class CObjFileStore
{
const string keyStr = "yourkey"; //加密的KEY字符,用MD5码生成128位KEY密钥
const string ivStr = "youriv"; //加密的IV字符,用MD5码生成128位IV密钥

/// <summary>
/// 将对象保存为文件
/// </summary>
/// <param name="uFilename">文件名及地址</param>
/// <param name="uTarget">保存对象,需[Serializable]</param>
static public void SaveObj(string uFilename, object uTarget)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream mStream = new MemoryStream();
formatter.Serialize(mStream, uTarget);
Rijndael rijn = Rijndael.Create();
MD5 md5 = MD5.Create();
byte[] Key = md5.ComputeHash(Encoding.ASCII.GetBytes(keyStr));
byte[] IV = md5.ComputeHash(Encoding.ASCII.GetBytes(ivStr));
FileStream fStream = new FileStream(uFilename, FileMode.Create, FileAccess.Write,
FileShare.None);
CryptoStream cStream = new CryptoStream(fStream, rijn.CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(cStream, Encoding.ASCII);
char[] data = Encoding.ASCII.GetChars(mStream.ToArray());
sWriter.Write(data);
sWriter.Flush();
sWriter.Close();
cStream.Close();
fStream.Close();
mStream.Close();
}

/// <summary>
/// 从文件读取对象
/// </summary>
/// <param name="uFilename">文件名及地址</param>
/// <returns>反序列化后的对象,类型为object</returns>
static public object LoadObj(string uFilename)
{
IFormatter formatter = new BinaryFormatter();
Rijndael rijn = Rijndael.Create();
MD5 md5 = MD5.Create();
byte[] Key = md5.ComputeHash(Encoding.ASCII.GetBytes(keyStr));
byte[] IV = md5.ComputeHash(Encoding.ASCII.GetBytes(ivStr));
FileStream fStream = new FileStream(uFilename, FileMode.Open, FileAccess.Read,
FileShare.Read);
CryptoStream cStream = new CryptoStream(fStream, rijn.CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
StreamReader sReader = new StreamReader(cStream);
string ftxt = sReader.ReadToEnd();
byte[] bytes = Encoding.ASCII.GetBytes(ftxt);
MemoryStream mStream = new MemoryStream(bytes);
object result = formatter.Deserialize(mStream);
sReader.Close();
cStream.Close();
fStream.Close();
mStream.Close();
return result;
}
}

当序列化的时候, 序列化进去5000个元素(list添加5000个字符串), 反序列化的时候, 只能序列化到下标为4629的元素, 以后的元素就提示超出下标范围, 当序列化进去10000个元素的时候, 直接提示
"未处理的异常: System.Runtime.Serialization.SerializationException: 在链接地址信
息中引用了 ID 为 4 的对象,但该对象并不存在。"
如果只序列化4629个或者少于4629个元素, 就正常, 请大神指出只能序列化4000多个元素的瓶颈在哪, 另外在unity3d的c#脚本中, 同样的代码只能序列化大概200来个元素, 超过的也是类似的提示, 一直没找到原因, 期待大神的解答
...全文
437 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
coder1988 2013-08-03
  • 打赏
  • 举报
回复
谢谢两位的帮助
soaringbird 2013-08-02
  • 打赏
  • 举报
回复
这样改:

//StreamWriter sWriter = new StreamWriter(cStream, Encoding.ASCII);
 //char[] data = Encoding.ASCII.GetChars(mStream.ToArray());
//sWriter.Write(data);
 mStream.Position = 0;
 mStream.CopyTo(cStream);
 //sWriter.Flush();
  //sWriter.Close();

 CryptoStream cStream = new CryptoStream(fStream, rijn.CreateDecryptor(Key, IV),
                CryptoStreamMode.Read);
//StreamReader sReader = new StreamReader(cStream);
           
  //string ftxt = sReader.ReadToEnd();
//byte[] bytes = Encoding.ASCII.GetBytes(ftxt);
 //MemoryStream mStream = new MemoryStream(bytes);
 MemoryStream mStream = new MemoryStream();
 cStream.CopyTo(mStream);
 mStream.Position = 0;
object result = formatter.Deserialize(mStream);
//sReader.Close();
真相重于对错 2013-08-02
  • 打赏
  • 举报
回复
try不要按char操作,而要按byte操作

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧