System.IO 二
接着上篇的来 System.IO
FileSystemWatcher





指向这个签名的方法
可以监听目录发生了什么事件







例如:
static void Main(string[] args)
{
Console.WriteLine("请开始你的表演:");
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"E:\Test"; //此目录一定需要存在,不然会引发 ArgumentException 异常
//设置需要 留意 的事情
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
//只观察文本文件
watcher.Filter = "*.txt";
//添加事件处理程序
watcher.Changed += new FileSystemEventHandler(Onchange);
watcher.Created += new FileSystemEventHandler(Onchange);
watcher.Deleted += new FileSystemEventHandler(Onchange);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
//开始观察目录
watcher.EnableRaisingEvents = true;
//等待用户退出程序
Console.WriteLine("请按 `q` 退出程序");
while (Console.Read() !='q');
}
static void Onchange(object source, FileSystemEventArgs e)
{
//指定当文件改变、创建或者删除的时候需要做的事情
Console.WriteLine("File:{0} {1}",e.FullPath,e.ChangeType);
}
static void OnRenamed(object source, RenamedEventArgs e)
{
//指定当文件重命名的时候需要做的事情
Console.WriteLine("File: {0} renamed to {1}",e.OldFullPath,e.FullPath);
}

对象序列化
序列化描述了持久化一个对象的状态到流(如文件流和内存流)的过程。序列化服务保存应用程序数据相对于IO命名空间的读读取器/编写器,减少了很多的麻烦。
在看列子之前,你先要理解一个类。




[Serializable] //序列化的对象需要标记为可以序列化
public class UserProp
{
public string WindowColor;
public int FontSize;
} Console.WriteLine("请开始你的表演:");
UserProp userData = new UserProp();
userData.WindowColor = "red";
userData.FontSize = ; //将一个对象保存到一个本地
BinaryFormatter binFormat = new BinaryFormatter();
using (Stream fStrem=new FileStream("Haha.txt", FileMode.Create, FileAccess.Write, FileShare.None))
{
binFormat.Serialize(fStrem,userData); //将对象序列化为流
}
Console.ReadLine();
虽然对象序列化保存对象非常简单,单幕后的调用过程非常复杂。除了保存为二进制格式外还可以保存为简单对象访问协议(SOAP)或XML格式。
最后要知道对象图可以持久化为任意的System.IO.Stream派生类型。
一组关联对象(包括基类和派生类)被总称为一个对象图。对象图提供一种很简明的方式来记载一组对象如何相互引用对方。
为序列化配置对象
为每个一个关联 的类(或结构)加上 [serializable] 特性,不参与到序列化配置中,可以在这么域前面加上 [NoSerialized]特性。
定义可序列化对象
[Serializable]
public class Radio
{
public bool hasTweeters;
public bool hasSubWoofers; [NonSerialized] //把此变量设置为不可序列化的
public string radioID = "X-Y110";
} [Serializable]
public class Car
{
public Radio theRadio = new Radio();
public bool isHatchBack;
} [Serializable]
public class JamesBondCar : Car
{
public bool canFly;
public bool canSubmerge;
}
注:[Serializable]特性不能被继承。因此,如果从被标记为[Serializable]的类派生一个类,子类也必须被标记为[Serializable],否则它不能持久化。
有一句话叫做公共的属性,私有的字段
一般的情况,是在一个类中,我们把字段定义为私有的,属性则定义为公共的。这句的来源则是我们在一个类中声明一个字段,然后把这个字段进行重构,封装字段。
[Serializable]
public class Person
{
//公共字段
public bool isAlive = true; //私有字段
private int personAge = ; //公共属性,私有字段
private string fName;
public string FName
{
get { return fName; }
set { fName = value; }
}
我们使用 BinaryFormatter或 SoapFormatter进行处理,都可以保存到所选的流中。然而,XmLSerializer不会保存personAge的值。
序列化格式方法
一旦将类型配置为参与.NET序列化,接下来就是选择当持久化对象图时使用哪种格式(二进制、SOAP或XML),有以下3中选择:
BinaryFormatter:
SoapFormatter:
XmlSerializer:
在引用不出命名空间的时候请去引用里面添加引用。
第一个上面说过了,是二进制格式。




这里我们可以了解下它的属性和方法,主要是序列化和反序列化的方法。SOAP是一个标准的XML格式。


有很的重载构造函数。


下面会介绍如何使用这三种格式序列化对象。
这三个都市直接派生于System.Object.
IFormatter和IremotingFormatting接口


我们来看看IFormatter接口





它们两个类继承同一个接口,而此接口中这两个主要的方法刚好符合我们的要求 。所有我们建立一个方法使用这两个类中的一个来序列化一个对象图。
/// <summary>
/// 两个类的通用方法
/// </summary>
/// <param name="itfFormat">BinaryFormatter或SoapFormatter的实例</param>
/// <param name="destStrem">准备的Stream流</param>
/// <param name="graph">需要写的序列化对象</param>
static void SerializeObjectGraph(IFormatter itfFormat, Stream destStrem, object graph)
{
itfFormat.Serialize(destStrem,graph);
}


在格式化程序中的类型保真
在3种格式化程序中,最明显不同是对象图被持久化为不同的流(二进制、SOAP或XML)的方式。BinaryFormatter在希望用值(例如以一个完整的副本)跨越.NET应用程序机器边界传递对象时成为理想的选择。当希望尽可能延伸持久化对象图的使用范围时,SoapFormatter和XmlSerializer是理想选择。
①使用BinaryFormatter序列化对象
Ⅰ Serialize():将一个对象图按字节顺序转化为一个对象图。
Ⅱ Deserialize():讲一个持久化的字节顺序转化为一个对象图。
static void Main(string[] args)
{
Console.WriteLine("请开始你的表演:"); JamesBondCar jbc = new JamesBondCar();
jbc.canFly = true;
jbc.canSubmerge = false;
jbc.theRadio.stationPresets = new double[] { 89.3, 105.1, 97.1 };
jbc.theRadio.hasTweeters = true; //以二进制格式保存car
SaveAsBinaryFormat(jbc,"CarDara.dat"); Console.ReadLine(); }
static void SaveAsBinaryFormat(object objGraph, string fileName)
{
BinaryFormatter binFormat = new BinaryFormatter();
using (Stream fStream=new FileStream(fileName,FileMode.Create,FileAccess.Write,FileShare.None))
{
binFormat.Serialize(fStream, objGraph);
}
Console.WriteLine("保存成功了");
}

使用BinaryFormatter反序列化对象,SOAP和XML反序列化类似
/// <summary>
/// 反序列化
/// </summary>
/// <param name="fileName">文件名</param>
static void LoadFormBinaryFile(string fileName)
{
BinaryFormatter binFormat = new BinaryFormatter();
using (Stream fStream=File.OpenRead(fileName))
{
JamesBondCar carFormDisk =(JamesBondCar)binFormat.Deserialize(fStream); //Deserialize返回的是object类型,转下型然后接收就可以了
Console.WriteLine("fly属性:{0}",carFormDisk.canFly);
}
}

②使用SoapFprmatter序列化对象
static void SaveAsSoapFormat(object objGraph,string fileName)
{
SoapFormatter soapFomat = new SoapFormatter();
using (Stream fStream=new FileStream(fileName,FileMode.Create,FileAccess.Write,FileShare.None))
{
soapFomat.Serialize(fStream,objGraph);
}
Console.WriteLine("保存Soap格式成功");
}

③使用XmlSerializer序列化对象
static void SaveAsXmlFormat(object objGraph, string fileName)
{
//此类的构成函数必须给参数,需要确定你对谁进行序列化
XmlSerializer xmlFormat = new XmlSerializer(typeof(JamesBondCar));
using (Stream fStream=new FileStream(fileName,FileMode.Create,FileAccess.Write,FileShare.None))
{
xmlFormat.Serialize(fStream,objGraph);
}
Console.WriteLine("序列化XML完成");
}

XmlSerializer要求对象图中的所有序列化类型支持默认的构造函数。没有的话需要加上
上面三种可以看出,XML格式是最清楚和简单的。
控制生成的XML数据
System.Xml.Serialization命名空间中的部分特性






例如:


如果想更深一点的了解可以去官网查看
序列化对象集合
前面已经演示了如何将一个对象持久化为一个流,下面演示如何保存一组对象。
一组对象就需要用到集合了。(数组、ArrayList或List<T>)。用数组代替我们之前用的单个对象就可以了
List<JamesBondCar> myCars = new List<JamesBondCar>()
{
new JamesBondCar(){ canFly=true, canSubmerge=false, isHatchBack=false},
new JamesBondCar(){ canFly=true, canSubmerge=true, isHatchBack=false},
new JamesBondCar(){ canFly=true, canSubmerge=false, isHatchBack=true},
}; //以二进制格式保存car
// SaveAsBinaryFormat(jbc, "CarDara.dat");
// LoadFormBinaryFile("CarDara.dat");
//SaveAsSoapFormat(jbc,"CarData.soap");
SaveAsXmlFormat(myCars,"CarData.xml");
Console.ReadLine();
static void SaveAsXmlFormat(List<JamesBondCar> objGraph, string fileName)
{
//此类的构成函数必须给参数,需要确定你对谁进行序列化
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<JamesBondCar>));
using (Stream fStream=new FileStream(fileName,FileMode.Create,FileAccess.Write,FileShare.None))
{
xmlFormat.Serialize(fStream,objGraph);
}
Console.WriteLine("序列化XML完成");
}

另外两个类似。
自定义Soap/Binary序列化过程
System.Runtime.Serizlization命名空间核心类型







深入了解对象序列化
当BinaryFormatter序列化一个对象图时,它负责传送下面的信息到指定的流。
①在对象图中对象的完全限定名(如 MyApp.Car)
②定义对象图的程序名称(如 MyApp.exe)
③SerizlizationInfo 类的一个实例,包含了所有由对象图成员保存的所有描述性数据
SoapFormatter也类似。
使用ISerizlizable自定义序列化
被标记了[Serializable]的对象拥有了实现ISerializable接口的选项。
这个接口就一个方法:






AddValue这个重载很多。

实现了ISerizlizable接口的类型也必须定义一个带有下面签名的特殊构造函数:






例如:
[Serializable]
public class StringData : ISerializable
{
private string dataItemOne = "First data block";
private string dataItemTwo = "More data";
public StringData()
{ }
protected StringData(SerializationInfo si,StreamingContext ctx)
{
//从流中得到合并的成员变量
dataItemOne = si.GetString("First_Item").ToLower();
dataItemTwo = si.GetString("dataItemTwo").ToLower();
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//用格式化数据填充SerizlizationInfo对象
info.AddValue("First_Item", dataItemOne.ToUpper());
info.AddValue("dataItemTwo", dataItemTwo.ToUpper());
}
}
StringData myData = new StringData();
SoapFormatter soapFprmat = new SoapFormatter();
using (Stream fStream=new FileStream("MyData.soap",FileMode.Create,FileAccess.Write,FileShare.None))
{
soapFprmat.Serialize(fStream,myData);
}

可以简单的完成
[OnSerializing]
private void OnSerializing(StreamingContext context) //需要带上此参数
{
//在序列化的过程就调用
dataItemOne = dataItemOne.ToUpper();
dataItemTwo = dataItemTwo.ToUpper();
} [OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
//在反序列化的过程就调用
dataItemOne = dataItemOne.ToLower();
dataItemTwo = dataItemTwo.ToLower();
}
这个命名空间介绍完了,涉及的类有点多。。。
System.IO 二的更多相关文章
- C#、.Net代码精简优化(空操作符(??)、as、string.IsNullOrEmpty() 、 string.IsNullOrWhiteSpace()、string.Equals()、System.IO.Path 的用法)
一.空操作符(??)在程序中经常会遇到对字符串或是对象判断null的操作,如果为null则给空值或是一个指定的值.通常我们会这样来处理: .string name = value; if (name ...
- System.IO中的File、FileInfo、Directory与DirectoryInfo类(实例讲解)
一.建立的文件夹(对这些文件进行以上四个类的操作): 父目录: 父目录的子目录以及父目录下的文件: 子目录下的文件: 二.效果图 三.代码实现 using System; using System.I ...
- 多种下载文件方式 Response.BinaryWrite(byte[] DocContent);Response.WriteFile(System.IO.FileInfo DownloadFile .FullName);Response.Write(string html2Excel);
通过html给xls赋值,并下载xls文件 一.this.Response.Write(sw.ToString());System.IO.StringWriter sw = new System.IO ...
- C# System.IO.Path
Path的常用方法 函数列表 对一个路径做相应操作,包括文件路径,目录路径,通常会用到Path这个类, 本文列举一些常用的操作. 获取指定路径字符串的目录信息 public static string ...
- C# System.IO 文件流输入输出
一.读写文本文件 可以用fileStream来读写文本文件,但是FileStream是通过字节形式来读写数据的,要把字节数据转换为文本,要自己处理编码转换. 对于文本文件的读写,通常用 StreamR ...
- Pipe——高性能IO(二)
Pipelines - .NET中的新IO API指引(一) Pipelines - .NET中的新IO API指引(二) 关于System.IO.Pipelines的一篇说明 System.IO.P ...
- 【等待事件】等待事件系列(3+4)--System IO(控制文件)+日志类等待
[等待事件]等待事件系列(3+4)--System IO(控制文件)+日志类等待 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可 ...
- Fiddler的一些坑: !SecureClientPipeDirect failed: System.IO.IOException
手机的请求Fiddler可以捕捉,但是手机一直无法上网,在logs中看到的日志如下: !SecureClientPipeDirect failed: System.IO.IOException 由于远 ...
- 服务 在初始化安装时发生异常:System.IO.FileNotFoundException: "file:///D:\testService"未能加载文件或程序集。系统找不到指定文件。
@echo.@if exist "%windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" goto INSTALL ...
随机推荐
- spark项目打jar包,不包含依赖包问题的解决方案
mvn clean package打包maven-archetype-webapp项目时,打包后的jar包含项目中引用的jar包(解压后,在WEB-INF有一个lib目录,该目录下有所有依赖包). m ...
- HTML6即将到来,你没有看错是HTML6
HTML6提案1:对视频对象的更多控制 我们可能永远不会解决与压缩编解码器的争斗,但我们可以与之配合.不同的压缩算法可能需要更多的工作来实现,但是它们提供竞争.能对展现在页面上的视频帧提供更多控制的方 ...
- LeetCode 222.完全二叉树的节点个数(C++)
给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置.若最底 ...
- malloc(0)分配多少内存?(译文)
原文地址:http://prog21.dadgum.com/179.html 在大多的系统中,这个C的小程序将会吸收全部空闲的内存. ){ ); } 在我们聊malloc(0)之前,让我们看看mall ...
- java.lang.IllegalArgumentException: Page directive: invalid value for import 问题处理
1.问题说明: 项目原来用的tomcat版本是apache-tomcat-6.0,后来为了安全原因将版本升至apache-tomcat-7.0,发现有的jsp页面出现下面的异常: java.lang. ...
- 同源策略引发对跨域jsonp跨域的理解
一,同源策略其实网络的安全基石,既:http://www.baidu.com:80协议(http或者HTTPS或者ws或者wss).域名(www.baidu.com).端口(默认80,可以不写 htt ...
- Memcache安装、配置与学习
基于现在大多网站数据很多,由于页面性能问题我们都开始对站点使用缓存进行性能优化 Memcache扩展下载:http://windows.php.net/downloads/pecl/releases/ ...
- oracle账户密码过期,修改为无限制
查看用户的proifle是哪个,一般是default: sql>SELECT username,PROFILE FROM dba_users; 查看指定概要文件(如default)的密码有效期设 ...
- 合并Gridview单元格
Introduction There are a lot of methods in the Internet solving the problem of how to merge GridView ...
- Hibernate课程 初探一对多映射5-2 Eclipse添加数据库连接
1 Eclipse新建java项目 2 Windows ==> show view == >other ==>Data source Explorer 3 左侧视图 database ...