.net序列化与反序列化——提供多次存储对象集后读取不完全解决方案
||问题:
文本文档读取序列化文件时只能读取第一次序列化对象或对象集,而多次序列化存到同一个文本文件中不能完全读取。最近做一个简单的学生管理系统,涉及到多次将学生对象序列化后追加存储到同一个文档中。在查看所有学生的时候总是读取不完全,折腾了好长时间,想到了以下一个相对权宜之策。
1、对象序列化反序列化简述
对象序列化是指将对象转化成流的过程。
反序列化与之相反,是将流转换成对象。这两个过程组合起来,就使得数据能轻松的以对象或对象集为单位进行存储传输。
2、序列化反序列化步骤
用serializable标识类
调用BinaryFormatter、soapFormatter或XmlSerializer将其序列化
反序列调用Deserialize
3、简单对象序列化与反序列化
说明问题:第二次追加存储到第一次的文档后面,反序列化时就不能读取所有已经序列化的对象,而只能读取第一次序列化的对象(集)。下面是出现这个问题的程序。
参考程序:
//引用他人资源说明一下问题局限性。只能序列化一次,再次追加存储后,如果反序列化就不能取出所有对象
//----------二进制方式,可以使用BinaryFormatter 类来以二进制格式将对象或整个连接对象图形序列化和反序列化
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic; namespace Formatter
{
[Serializable]
public class Account
{
public int UserID;
public string Username;
}
class BinaryFormatterTest
{
public void BinaryFormat()
{
Account[] accounts = {
new Account(){ UserID = 1, Username = "test1" },
new Account(){ UserID = 2, Username = "test2" },
new Account(){ UserID = 3, Username = "test3" }
}; string savePath = @"e:\BinarySerializerTest.bin";
BinaryFormatter formatter = new BinaryFormatter(); using (FileStream writeStream = new FileStream(savePath, FileMode.Append, FileAccess.Write)) //这边是Create没问题,但如果追加根本读不完啊
{
formatter.Serialize(writeStream, accounts); //这里面只序列化一次,读者可以试着在序列化一次试试,或者在运行一次,追加存储
//formatter.Serialize(writeStream, accounts); //追加存储,取就会出问题 writeStream.Close();
using (FileStream readStream = new FileStream(savePath, FileMode.Open, FileAccess.Read))
{
Account[] deSerializedValue = formatter.Deserialize(readStream) as Account[];
if (deSerializedValue != null && deSerializedValue.Length > 0)
{
for (int i = 0; i < deSerializedValue.Length; i++)
{
Console.WriteLine("{0}\tUserID = {1}, Username = {2}", i, deSerializedValue[i].UserID, deSerializedValue[i].Username);
}
}
}
}
Console.ReadKey();
} }
}
4、解决办法:
设第二次序列化的集合为List<Student>stuList,在第二次序列化之前,把第一次序列化的对象集反序列化取出,存储到List<类>的泛型化集合stuListRead中,然后用foreach语句将stuListRead中的所有元素添加到stuList中,然后一起序列化,覆盖原文件存储。
这里面会遇到一个问题,就是原文件为空的情况,反序列化取出存储到stuList集合时,就会出现“流为空”异常,读者可以在反序列化之前进行文件信息判断,fi.Length?=0;如果不等于0在进行反序列化即可。读者可以参考以下程序。
5、Student类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace StudentManagement
{
/*
添加一个学生类Student,该类封装学生的一些基本信息(学号、姓名、年龄等字段),
* 重载一个带参数的构造函数,为学生的基本信息字段初始化。*/
[Serializable]
class Student
{
private int stuNum; //学号 public int StuNum
{
get { return stuNum; }
set { stuNum = value; }
} private string stuName; //姓名 public string StuName
{
get { return stuName; }
set { stuName = value; }
} private string stuSex; //性别 public string StuSex
{
get { return stuSex; }
set { stuSex = value; }
} private string stuMajor; //专业 public string StuMajor
{
get { return stuMajor; }
set { stuMajor = value; }
} private string stuClass; //班级 public string StuClass
{
get { return stuClass; }
set { stuClass = value; }
} //构造函数初始化
public Student(int stuNum, string stuName, string stuSex, string stuMajor, string stuClass)
{
this.stuNum = stuNum;
this.stuName = stuName;
this.stuSex = stuSex;
this.stuMajor = stuMajor;
this.stuClass = stuClass;
}
}
}
6、FileAccessOperate文件操作类
导入命名空间
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
定义一个文件目录项:
static string txtDictionary=@"e:\01111104\";
反序列化读方法:
//读方法
public List<Student> StuRead()
{
string path=txtDictionary+"stu.dat"; //学生信息存储路径 FileStream stream = new FileStream(path,FileMode.Open,FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter(); //创建序列化对象
List<Student> stuList; stuList = bf.Deserialize(stream) as List<Student>; stream.Close();
return stuList;
}
序列化写方法:
//写方法
public void StuWrite(List<Student> stuList)
{
string path = txtDictionary + "stu.dat"; //学生信息存储路径 FileInfo fi = new FileInfo(path); //判断文件是否存在
if (fi.Exists == false)
{
FileStream fs = new FileStream(path,FileMode.Create);
fs.Close();
fi = new FileInfo(path);
}
//判断文件是否为空,即是否是第一次序列化存储
if (fi.Length > 0)
{
//如果不为空,即已经进行过序列化存储,需将之前存的信息,反序列化读取,添加到要存储的对象集,覆盖存储
List<Student> StuListRead = StuRead(); foreach (Student stu in StuListRead)
{
stuList.Add(stu);
}
} Stream stream = new FileStream(path, FileMode.Create, FileAccess.Write);
BinaryFormatter bf = new BinaryFormatter(); //创建序列化对象 //序列化
bf.Serialize(stream, stuList);
stream.Close();
}
7、总结
这样就能解决对象集每次只能读取第一次序列化的问题,这样能把所有存储的学生对象全部读出。关键在于每次序列化后都产生独立的对象集存储在文本文档中,够每次序列化只能读取第一个对象集。通过在写之前进行读取,和要写的对象集合并成一个对象集重新覆盖写入,实际上文本文档中只存储了一个对象集,这样就能反序列化读取所有对象。
.net序列化与反序列化——提供多次存储对象集后读取不完全解决方案的更多相关文章
- C#对象序列化与反序列化zz
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...
- C#对象序列化与反序列化
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍.......................... ...
- Java对象的序列化与反序列化
序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等.在网络传输过程中,可以是字节或是 ...
- [转载]C#对象序列化与反序列化
文章写的实在是太好了,忍不住转来: http://www.cnblogs.com/LiZhiW/p/3622365.html#_Toc8478 1.对象序列化的介绍 (1).NET支持对象序列化的几种 ...
- Java基础18:Java序列化与反序列化
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- Hessian 序列化和反序列化实现
先聊聊 Java的序列化,Java官方的序列化和反序列化的实现被太多人吐槽,这得归于Java官方序列化实现的方式. 1.Java序列化的性能经常被吐槽.2.Java官方的序列化后的数据相对于一些优秀的 ...
- 夯实Java基础系列22:一文读懂Java序列化和反序列化
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- Java 序列化和反序列化(二)Serializable 源码分析 - 1
目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...
- 详解电子表格中的json数据:序列化与反序列化
从XML到JSON 当下应用开发常见的B/S架构之下,我们会遇到很多需要进行前后端数据传输的场景.而在这个传输的过程中,数据通过何种格式传输.方式是否迅速便捷.书写方式是否简单易学,都成为了程序员在开 ...
随机推荐
- DICOM医学图像处理:WEB PACS初谈二,图像的传输
背景: 如前一篇专栏博文所述,借助于CGI或FastCGI技术转发浏览器发送过来的用户请求,启动本地的DCMTK和CxImage库响应.然后将处理结果转换成常规图像返回到浏览器来实现Web PACS. ...
- 用HTML5canvas绘制一个圆环形的进度表示
先看一下画出来的效果,如下图,这样一个圆环形的进度. 我这里使用HTML5的Canvas来要制作这样一个圆环形的进度, 首先是HTML页面,HTML5的文档标识是: 这个文档标识要比HTML4的简单 ...
- java游戏开发基础Swing之JRadioButton
© 版权声明:本文为博主原创文章,转载请注明出处 1.按钮(JButton) Swing中的按钮是JButton,它是javax.swing.AbstractButton类的子类,Swing中的按钮可 ...
- Android版CSDN发现的一些问题
作为CSDN的忠有用户,在他一推出这款APP以后.就下载了使用,近期发现了一些个问题,在此提出来.希望看到或者遇到同样问题的,提出你们的解决方式. 在CSDN手机版的首页上,我 ...
- MySQL四-2:完整性约束
阅读目录 一 介绍 二 not null与default 三 unique 四 primary key 五 auto_increment 六 foreign key 七 作业 一 介绍 约束条件与数据 ...
- hdu 2349 最小生成树
/* 刚開始想错了,我以为必须是相邻的点才干连接.原来无线距离能够随意连接 对最小生成树理解不够深啊 */ #include<stdio.h> #include<math.h> ...
- ApplicationContextRunner如何简化自动配置测试
1. 概览 众所周知,自动配置是Spring Boot的关键功能之一, 但测试自动配置可能会很棘手. 在以下部分中,我们将展示ApplicationContextRunner如何简化自动配置测试. 2 ...
- webpack 功能大全 【环境配置】
1. webpack简介 webpack 是一个模块打包工具.它使得模块相互依赖并且可构建等价于这些模块的静态资源.相比于已经存在的模块打包器(module bundler),webpack的开发动机 ...
- [Java]事件驱动程序设计
事件驱动模型三大要素 1)事件源:能接收外部事件的源体: 2)监听器xListener:能接收事件源通知的对象: 3)处理器Handler:用于处理事件的对象. 在Java中使用监听器对象处理事件的方 ...
- codeforces #364d As Fast As Possible
题意:一群学生,要到离这里为l的地方去.有一辆车,车只有k个座位.人和车的速度分别v1,v2,问你所有人到达的最小时间. 思路:数学题.最小时间就是要求所有同学同时到达.每个同学最多上一次车.那么显然 ...