.NET框架免安装与序列化的一些东东

最近在做一个领导交派的任务,是写一个单机版的数据填报与汇总的小软件,说它小,是因为并无多么复杂的功能,也没有什么特别的技术难点,但是实现起来比较麻烦,比较复杂。

 

这个软件的一个基本需求,是基于单机版操作,也就是填报的数据保存为本地文件,然后用多个文件可以汇总计算新的结果。对于这个需求,一开始就想到用自定义的文件格式保存和读取数据,后来想到可以直接用对象的序列化保存和反序列化来实现。但是实现过程中,还是有具体的问题需要解决。

 

一、关于免安装.NET框架运行.NET程序

 

用虚拟机装了一个干净的winXPSP2,没有.NET框架,作为测试机。简便快捷起见,我采用了《通过FetionVM实现无.net框架环境下运行.NET程序(转)》一文中的方法,实现了.NET框架的免安装,而且这样做出来的程序,可以不用做安装包,是绿色软件。

 

不过,这其中还有一点需要注意,那就是飞信做的这个虚拟机,只是为了满足飞信的需求的,而对于自己做的.NET程序来说,这个虚拟环境的内容可能不够用。这不,我的这个软件,在测试机上运行时,点击一个按钮时,会报FileNotFoundException异常,如下图所示,非常奇怪。这个按钮实际上是要打开一个选择文件夹的对话框,代码中并没有要找什么文件的内容。仔细查看了一下代码,发现这个对话框需要system.design.dll,而飞信的虚拟机中没有它,把它加到飞信虚拟机的System目录下,就OK了。

 

.NET框架免安装与序列化的一些东东

FileNotFoundException异常


二、关于序列化的具体方法

 

关于对象的序列化与反序列化,查查网上,查查MSDN,都有很简明的例子,而且方式有二进制、XML的。为了保持程序数据一定的保密性,故决定采取二进制格式的序列化,这个倒是简单,直接用以下代码,即可直接实现对象序列化的二进制文件和反序列化:

 

序列化:

IFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(strFilePath, FileMode.Create);
formatter.Serialize(fs, obj);
fs.Close();

 

反序列化:

IFormatter formatter = new BinaryFormatter();

FileStream fs = new FileStream(strFilePath, FileMode.Open);
DataFile obj = (DataFile)formatter.Deserialize(fs);
fs.Close();//文件使用完毕之后一定要关闭
return obj;

 

然而,这样序列化出来的文件,实际上里面是明文的,用ultraedit之类的文本编辑器打开序列化后的文件的话,可以清楚地看到里面保存了类里面的的成员变量名称、值等,所以如果为了提高保密性,其实需要对其进行加密。但是,上面这种方法,formatter.Serialize(fs, obj);这句会把序列化后的流直接写进文件,而没有加密的机会,所以想加密的话,需要在写入文件之前加密好,所以可以考虑序列化到内存流中,然后加密,然后写入文件的方法:

 

IFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
formatter.Serialize( ms, obj );
FileStream fs = new FileStream( strFilePath, FileMode.Create );
BinaryWriter bw = new BinaryWriter( fs, Encoding.Default );
                
bw.Write( ms.ToArray() );
bw.Write( strMD5PWD );  //strMD5PWD是转换成MD5串之后的密钥,可用它对内存流加密

bw.Close();
fs.Close();
ms.Close();

 

上面这段代码,可以说是为加密做好了准备工作,但用户暂时没有对加密提出明确要求,故暂时未实现加密。若实现加密,反序列化时,也不能直接用DataFile obj = (DataFile)formatter.Deserialize(fs),而是也需要先读出字节流,然后将其中MD5密钥截取,用其解密后,再反序列化回去。

 

这里还有一个需要注意的地方,就是在序列化时,不能使用StreamWriter,因为它操作的除了字符串,就是字符数组,而没有字节数组,而二进制序列化后的字节流,若转换成字符串或字节数组的话,会丢失数据。比如整数值序列化后无法反序列化之类。

 

三、关于反序列化时的程序集异常

 

把编译好的程序放在测试机上运行,发现在反序列化时捕获了一个找不到程序集的异常:

.NET框架免安装与序列化的一些东东

找不到程序集异常

对程序集的概念了解得不是很多,但是在网上查了一下,找到了一个解决方案,即《反序列化无法找到程序集(转载)》一文的方法,简单易行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值