精通C#---文件输入输出和对象序列化

1.System.IO

BinaryReader和BinaryWriter 
BufferedStream 为字节流提供临时存储空间
Directory和DirectoryInfo 
DriveInfo
File和FileInfo
FileStream
FileSystemWatcher
MemoryStream
Path
StreamWriter和StreamReader
StringWriter和StringReader

FileSystemInfo

Attributes
CreationTime
Exists
Extension
FullName
LastAccessTime
LastWriteTime
Name
Delete
Refresh

DirectoryInfo

Create和CreateSubdirectory
Delete
GetDirectories
GetFiles
MoveTo
Parent
Root


//
class Program
{
	static void Main()
	{
		ShowWindowsDirectoryInfo();
		Console.ReadLine();
	}

	static void ShowWindowsDirectoryInfo()
	{
		DirectoryInfo dir = new DirectoryInfo(@"C:\Windows");
		// dir.FullName
		// dir.Name
		// dir.Parent
		// dir.CreationTime
		// dir.Attributes
		// dir.Root
	}
}

//
static void DisplayImageFiles()
{
	DirectoryInfo dir = new DirectoryInfo(@"C:\Windows\Web\Wallpaper");
	FileInfo[] imageFiles = dir.GetFiles("*.jpg", SearchOption.AllDirectories);
	// imageFiles.Length
	foreach(FileInfo f in imageFiles)
	{
		// f.Name
		// f.Length
		// f.CreationTime
		// f.Attributes
	}
}

//
static void ModifyAppDirectory()
{
	DirectoryInfo dir = new DirectoryInfo(@"C:\");
	dir.CreateSubdirectory("MyFolder");
	dir.CreateSubdirectory(@"MyFolder2\Data");
}

//
static void ModifyAppDirectory()
{
	DirectoryInfo dir = new DirectoryInfo(".");
	dir.CreateSubdirectory("MyFolder");
	DirectoryInfo myDataFolder = dir.CreateSubdirectory(@"MyFolder2\Data");
	// myDataFolder
}

// 
static void FunWithDirectoryType()
{
	string[] drives = Directory.GetLogicalDrives();
	foreach(string s in drives)
	{
		// s
	}

	Console.ReadLine();
	try
	{
		Directory.Delete(@"C:\MyFolder");
		Directory.Delete(@"C:\MyFolder2", true);
	}
	catch(IOException e)
	{
		Console.WriteLine(e.Message);
	}
}

//
class Program
{
	static void Main()
	{
		DriveInfo[] myDrives = DriveInfo.GetDrives();
		foreach(DriveInfo d in myDrives)
		{
			// d.Name
			// d.DriveType
			if(d.IsReady)
			{
				// d.TotalFreeSpace
				// d.DriveFormat
				// d.VolumeLabel
			}
		}
	}
}

FileInfo

AppendText
CopyTo
Create
CreateText
Delete
Directory
DirectoryName
Length
MoveTo
Name
Open
OpenRead
OpenText
OpenWrite

//
static void Main()
{
	using(FileStream fs = File.Create(@"C:\Test.dat"))
	{}

	using(FileStream fs2 = File.Open(@"C:\Test2.dat", FileMode.OpenOrCreate, FileAccess.ReadWriter, FileShare.None))
	{}

	using(FileStream readOnlyStream = File.OpenRead(@"Test3.dat"))
	{}

	using(FileStream writeOnlyStream = File.OpenWrite(@"Test4.dat"))
	{}

	using(StreamReader sreader = File.OpenText(@"C:\boot.ini"))
	{}
	
	using(StreamWriter swriter = File.CreateText(@"C:\Test6.txt"))
	{}

	using(StreamWriter swriterAppend = File.AppendText(@"C:\FinalTest.txt"))
	{}
}

File:
ReadAlllBytes
ReadAllLines
ReadAllText
WriteAllBytes
WriteAllLines
WriteAllText

//
class Program
{
	static void Main()
	{
		string[] myTasks = 
		{
			"Fix bathroom sink",
			"Call Dave",
			"Call Mom and Dad",
			"Play Xbox 360"
		};

		File.WriteAllLines(@"C:\tasks.txt", myTasks);
		foreach(string task in File.ReadAllLines(@"C:\tasks.txt"))
		{
			// task
		}
	}
}

Stream

CanRead,CanWrite,CanSeek
Close
Flush
Length
Position
Read和ReadByte
Seek
SetLength
Write和WriteByte

//
static void Main()
{
	using(FileStream fStream = File.Open(@"C:\myMessage.dat", FileMode.Create))
	{
		string msg = "Hello!";
		byte[] msgAsByteArray = Encoding.Default.GetBytes(msg);
		fStream.Write(msgAsByteArray, 0, msgAsByteArray.Length);
		fStream.Position = 0;
		byte[] bytesFromFile = new byte[msgAsByteArray.Length];
		for(int i = 0; i < msgAsByteArray.Length; i++)
		{
			bytesFromFile[i] = (byte)fStream.ReadByte();
			// bytesFromFile[i]
		}

		// Encoding.Default.GetString(bytesFromFile)
	}
}

StreamWriter和StreamReader

TextWriter:
Close
Flush
NewLine
Write
WriteLine

static void Main()
{
	using(StreamWriter writer = File.CreateText("reminders.txt"))
	{
		for(int i = 0; i < 10; i++)
			writer.Write(i + " ");

		writer.Write(writer.NewLine);
	}
}

TextReader:
Peek
Read
ReadBlock
ReadLine
ReadToEnd

static void Main()
{
	using(StreamReader sr = File.OpenText("reminders.txt"))
	{
		string input = null;
		while((input = sr.ReadLine()) != null)
		{
			Console.WriteLine(input);
		}
	}
}	

static void Main()
{
	using(StreamWriter writer = new StreamWriter("reminders.txt"))
	{...}
	using(StreamReader sr = new StreamReader("reminders.txt"))
	{...}
}


//
static void Main()
{
	using(StringWriter strWriter = new StringWriter())
	{
		strWriter.WriteLine("Don't forget Mother's Day this year...");
		Console.WriteLine("{0}", strWriter);
	}

	//
	using(StringWriter strWriter = new StringWriter())
	{
		strWriter.WriteLine("Don't forget Mother's Day this year...");
		// strWriter
		StringBuilder sb = strWriter.GetStringBuilder();
		sb.Insert(0, "Hey!! ");
		// sb.ToString()
		sb.Remove(0, "Hey!! ".Length);
		// sb.ToString()
	}
}

//
using(StringWriter strWriter = new StringWriter())
{
	strWriter.WriteLine("Don't forget Mother's Day this year...");
	// strWriter
	using(StringReader strReader = new StringReader(strWriter.ToString()))
	{
		string input = null;
		while((input = strReader.ReadLine()) != null)
		{
			Console.WriteLine(input);
		}
	}
}

BinaryWriter和BinaryReader

BinaryWriter:
BaseStream
Close
Flush
Seek
Write

BinaryReader:
BaseStream
Close
PeekChar
Read
ReadXXX

static void Main()
{
	FileInfo f = new FileInfo("BinFile.dat");
	using(BinaryWriter bw = new BinaryWriter(f.OpenWrite()))
	{
		// bw.BaseStream
		double aDouble = 1234.67;
		int anInt = 34567;
		string aString = "A, B, C";
		bw.Write(aDouble);
		bw.Write(anInt);
		bw.Write(aString);
	}
}

//
static void Main()
{
	FileInfo f = new FileInfo("BinFile.dat");
	using(BinaryReader br = new BinaryReader(f.OpenRead()))
	{
		// br.ReadDouble()
		// br.ReadInt32()
		// br.ReadString()
	}
}

2.以编程方式“观察”文件

public enum NotifyFilters
{
	Attributes,
	CreationTime,
	DirectoryName,
	FileName,
	LastAccess,
	LastWrite,
	Security,
	Size
}

// FileSystemEventHandler
void MyNotificationHandler(object source, FileSystemEventArgs e);
// RenamedEventHandler
void MyRenamedHandler(object source, RenamedEventArgs e);

static void Main()
{
	FileSystemWatcher watcher = new FileSystemWatcher();
	try
	{
		watcher.Path = @"C:\MyFolder";
	}
	catch(ArgumentException ex)
	{
		// ex.Message
		return;
	}
	
	watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
	watcher.Filter = "*.txt";
	watcher.Changed += new FileSystemEventHandler(OnChanged);
	watcher.Created += new FileSystemEventHandler(OnChanged);
	watcher.Deleted += new FileSystemEventHandler(OnChanged);
	watcher.Renamed += new RenamedEventHandler(OnRenamed);
	
	watcher.EnableRaisingEvents = true;
	while(Console.Read() != 'q');
}

static void OnChanged(object source, FileSystemEventArgs e)
{
	// e.FullPath
	// e.ChangeType
}

static void OnRenamed(object source, RenamedEventArgs e)
{
	// e.OldFullPath, e.FullPath
}

对象序列化

[Serializable]
public class UserPrefs
{
	public string WindowColor;
	public int FontSize;
}

static void Main()
{
	UserPrefs userData = new UserPrefs();
	userData.WindowColor = "Yellow";
	userData.FontSize = 50;

	BinaryFormatter binFormat = new BinaryFormatter();
	using(Stream fStream = new FileStream("user.dat", FileMode.Create, FileAccess.Write, FileShare.None))
	{
		binFormat.Serialize(fStream, userData);
	}
	// Console.ReadLine();
}

对象图的作用
为了让一个对象支持.NET序列化服务,每一个关联的类或结构加上[Serializable]特性。
给定类型的一些成员不参与序列化,可在这些域前加上[NonSerialized]。

[Serializable]
public class Radio
{
	public bool hasTweeters;
	public bool hasSubWoofers;
	public double[] stationPresents;

	[NonSerialized]
	public string radioID = "XF-552RR6";
}


[Serializable]
public class Car
{
	public Radio theRadio = new Radio();
	public bool isHatchBack;
}

[Serializable]
public class JamesBondCar : Car
{
	public bool canFly;
	public bool canSubmerge;
}

如果使用BinaryFormatter或SoapFormatter持久化一个对象,无论公共,私有字段都可以。
如果使用XmlSerializer,只有公共字段,和 拥有公共属性的私有数据可被序列化。

[Serializable]
public class Person
{
	public bool isAlive = true;
	private int personAge = 21;
	private string fName = string.Empty;
	public string FirstName
	{
		get{ return fName; }
		set{ fName = value; }
	}
}

对BinaryFormatter或SoapFormatter,isAlive,personAge,fName都是可序列化的。
对XmlSerializer,isAlive,fName是可序列化的。

BinaryFormatter, SoapFormatter

public interface IFormatter
{
	SerializationBinder Binder { get; set; }
	StreamingContext Context { get; set; }
	ISurrogateSelector SurrogateSelector { get; set; }
	object Deserialize(Stream serializationStream);
	void Serialize(Stream serializationStream, object graph);
}

public interface IRemotingFormatter : IFormatter
{
	object Deserialize(Stream serializationStream, HeaderHandler handler);
	void Serialize(Stream serializationStream, object graph, Header[] headers);
}

static void SerializeObjectGraph(IFormatter itfFormat, Stream destStream, object graph)
{
	itfFormat.Serialize(destStream, graph);
}

BinaryFormatter,不仅仅将对象图中对象的字段数据持久化,也持久化每个类型的完全限定名和定义程序集的完整名称。
SoapFormatter和XmlSerializer更具通用性。

BinaryFormatter:
static void Main()
{
	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;
	SaveAsBinaryFormat(jbc, "CarData.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("xxx");
}


static void LoadFromBinaryFile(string fileName)
{
	BinaryFormatter binFormat = new BinaryFormatter();
	using(Stream fStream = File.OpenRead(fileName))
	{
		JamesBondCar carFromDisk = (JamesBondCar)binFormat.Deserialize(fStream);
		// carFromDisk.canFly
	}
}

SoapFormatter:
static void SaveAsSoapFormat(object objGraph, string fileName)
{
	SoapFormatter soapFormat = new SoapFormatter();
	using(Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
	{
		soapFormat.Serialize(fStream, objGraph);
	}
}

XmlSerializer:
// 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);
	}
}

控制生成的XML数据

XmlAttribute
XmlElement
XmlEnum
XmlRoot
XmlText
XmlType

[Serializable, XmlRoot(Namespace = "http://www.MyCompany.com")]
public class JamesBondCar : Car
{
	[XmlAttribute]
	public bool canFly;
	[XmlAttribute]
	public bool canSubmerge;
}

//
[Serializable, XmlRoot(Namespace="http://www.MyCompany.com")]
public class JamesBondCar : Car
{
public JamesBondCar(bool skyWorthy, bool seaWorthy)
{
	canFly = skyWorthy;
	canSubmerge = seaWorthy;
}

public JamesBondCar()
{}

...
}

static void SaveListOfCars()
{
	List<JamesBondCar> myCars = new List<JamesBondCar>();
	myCars.Add(new JamesBondCar(true, true));
	myCars.Add(new JamesBondCar(true, false));
	myCars.Add(new JamesBondCar(false, true));
	myCars.Add(new JamesBondCar(false, false));
	
	using(Stream fStream = new FileStream("CarCollection.xml", FileMode.Create, FileAccess.Write, FileShare.None))
	{
		XmlSerializer xmlFormat = new XmlSerializer(typeof(List<JamesBondCar>));
		xmlFormat.Serialize(fStream, myCars);
	}

	// Save list of cars
}

//
static void SaveListOfCarsAsBinary()
{
	List<JamesBondCar> myCars = new List<JamesBondCar>();
	BinaryFormatter binFormat = new BinaryFormatter();
	using(Stream fStream = new FileStream("AllMyCars.dat", FileMode.Create, FileAccess.Write, FileShare.None))
	{
		binFormat.Serialize(fStream, myCars);
	}

	// 
}

System.Runtime.Serialization

ISerializable
ObjectIDGenerator
[OnDeserialized]    允许指定方法在对象被反序列化后立即调用
[OnDeserializing]   允许指定方法在对象被反序列化前被调用
[OnSerialized]		允许指定方法在对象被序列化后被调用
[OnSerializing]     允许指定方法在对象被序列化前被调用
[OptionalField]     允许在类型中定义一个可能在指定流中丢失的字段
[SerializationInfo] 

BinaryFormatter:
对象图中对象的完全限定名
对象图的程序集名称
SerializationInfo类的一个实例

自定义序列化过程

public interface ISerializable
{
	void GetObjectData(SerializationInfo info, StreamingContext context);
}

public sealed class SerializationInfo
{
	public SerializationInfo(Type type, IFormatterConverter converter);
	public string AssemblyName{ get; set; }
	public string FullTypeName{ get; set; }
	public int MemberCount{ get; }
	public void AddValue(string name, short value);
	public void AddValue(string name, ushort value);
	public void AddValue(string name, int value);
	...
}

[Serializable]
class SomeClass : ISerializable
{
	protected SomeClass(SerializationInfo si, StreamingContext ctx)
	{
		...
	}
	...
}

// 自定义实例化举例1
[Serializable]
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();
	}

	void ISerializable.GetObjectData(SerializationInfo info, StreamingContext ctx)
	{
		info.AddValue("First_Item", dataItemOne.ToUpper());
		info.AddValue("dataItemTwo", dataItemTwo.ToUpper());
	}
}

static void Main()
{
	StringData myData = new StringData();
	SoapFormatter soapFormat = new SoapFormatter();
	using(Stream fStream = new FileStream("MyData.soap", FileMode.Create, FileAccess.Write, FileShare.None))
	{
		soapFormat.Serialize(fStream, myData);
	}
}


// 自定义实例化举例2
[Serializable]
class MoreData
{
	private string dataItemOne = "First data block";
	private string dataItemTwo = "More data";
	[OnSerializing]
	private void OnSerializing(StreamingContext context)
	{
		dataItemOne = dataItemOne.ToUpper();
		dataItemTwo = dataItemTwo.ToUpper();
	}

	[OnSerialized]
	private void OnDeserialized(StreamingContext context)
	{
		dataItemOne = dataItemOne.ToLower();
		dataItemTwo = dataItemTwo.ToUpper();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值