C#2008与.NET 3.5 高级程序设计读书笔记(20)-- 文件输入输出和隔离存储
1.System.IO命名空间
System.IO命名空间主要包括基于文件和基于内存的输入输出(I/O)服务的相关类库.它们大多数包含在mscorlib.dll中,另外一部分则包含在System.dll中.System.IO命名空间中的多数类型主要用于编程操作物理目录和文件,而另一些类型则提供了从字符串缓冲区和类存区域中读写数据的方法.
2.Directory(Info)和File(Info)类型
如图,Directory和File直接继承System.Object类型,DirectoryInfo和FileInfo则继承FileSystemInfo抽象类.
一般来说,FileInfo和DiretoryInfo是获取文件或目录细节更好的方式,因为它们的成员往往会返回强类型的对象.而Directory和File类成员往往只返回简单字符串.
如果希望快速获取文件句柄的话,使用File类型可以节省很多代码,然而,使用FileInfo对象的好处是能从FileSystemInfo抽象基类定义的成员中获取文件属性.
(1)DirectoryInfo例子:
//绑定到目录
DirectoryInfo dir = new DirectoryInfo(@"C:\Windows\Web\Wallpaper");
// Get all files with a *.bmp extension.
FileInfo[] imageFiles = dir.GetFiles("*.jpg");
// How many were found?
Console.WriteLine("Found {0} *.jpg files\n", imageFiles.Length);
// Now print out info for each file.
foreach (FileInfo f in imageFiles)
{
Console.WriteLine("***************************");
Console.WriteLine("File name: {0}", f.Name);
Console.WriteLine("File size: {0}", f.Length);
Console.WriteLine("Creation: {0}", f.CreationTime);
Console.WriteLine("Attributes: {0}", f.Attributes);
Console.WriteLine("***************************\n");
}
(2)FileInfo例子
大部分FileInfo成员返回一个I/O相关的特定对象(FileStream,StreamWriter等).
a.FileInfo.Create()方法
//建立文件句柄
FileInfo f = new FileInfo(@"C:\test.dat");
FileStream fs = f.Create();
//使用FileStream对象
//...
//关闭文件流
fs.Close();
或者
//建立文件句柄
FileInfo f = new FileInfo(@"C:\test.dat");
using (FileStream fs = f.Create())
{
//使用FileStream对象
}
b.FileInfo.Open()方法
我们能使用FileInfo.Open()方法来打开现有文件,同时也可以利用它来创建新文件.
//建立文件句柄
FileInfo f2 = new FileInfo(@"C:\test.dat");
//第一个参数由枚举FileMode指定I/O请求的基本方式,比如所新建文件,打开现有文件和追加文件等
//第二个参数由枚举FileAccess指定基层流的读写行为
//第三个参数由枚举FileShare指定文件在其他的文件处理程序中的共享方式
using (FileStream fs = f2.Open(FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None))
{
//使用FileStream对象
}
c.FileInfo.OpenRead()和FileInfo.OpenWrite()
//得到一个只读的FileStream对象
FileInfo f3 = new FileInfo(@"C:\test.dat");
using (FileStream readOnlyStream = f3.OpenRead())
{
//使用FileStream对象
}
//得到一个只写的FileStream对象
FileInfo f4 = new FileInfo(@"C:\test.dat");
using (FileStream writeOnlyStream = f4.OpenWrite())
{
//使用FileStream对象
}
d.FileInfo.OpenText()
//得到一个StreamReader对象
FileInfo f5 = new FileInfo(@"C:\test.dat");
//StreamReader类型提供了提供了从基层文件读取字符数据的方法
using (StreamReader sreader = f5.OpenText())
{
//使用StreamReader对象
}
e.FileInfo.CreateText()和FileInfo.AppendText()
//得到一个StreamWriter对象
FileInfo f6 = new FileInfo(@"C:\test.dat");
//StreamWriter类型提供了提供了从基层文件写入字符数据的方法
using (StreamWriter sWriter = f6.CreateText())
{
//使用StreamWriter对象
}
3.StreamWriter和StreamReader类型
直接使用FileStream类型,有一个缺点是需要操作原始字节.而是使用各种文本Stream包装类,来处理文本数据和.NET类型.
// Get a StreamWriter and write string data.
using (StreamWriter writer = File.CreateText(""))
{
writer.WriteLine("Don't forget Mother's Day this year...");
writer.WriteLine("Don't forget Father's Day this year...");
writer.WriteLine("Don't forget these numbers:");
for (int i = 0; i < 10; i++)
writer.Write(i + " ");
// Insert a new line.
writer.Write(writer.NewLine);
}
// Now read data from file.
Console.WriteLine("Here are your thoughts:\n");
using (StreamReader sr = File.OpenText("reminders.txt"))
{
string input = null;
while ((input = sr.ReadLine()) != null)
{
Console.WriteLine(input);
}
}
或者直接创建StreamWriter和StreamReader类型
using (StreamWriter writer = new StreamWriter("reminders.txt"))
{
}
using (StreamReader sr = new StreamReader("reminders.txt"))
{
}
4.StringWriter和StringReader类型
使用StringWriter和StringReader类型我们可以将文本信息当作内存中的字符一样来处理.相应的代码和StreamWriter,StreamReader类似,只是StringWriter和StringReader是基于一段字符数据,而StreamWriter,StreamReader是基于一个文件.
// Create a StringWriter and emit character data to memory.
using (StringWriter strWriter = new StringWriter())
{
strWriter.WriteLine("Don't forget Mother's Day this year...");
// Get a copy of the contents (stored in a string) and pump
// to console.
Console.WriteLine("Contents of StringWriter:\n{0}", strWriter);
#region Get the underlying StringBuilder
// Get the internal StringBuilder.
StringBuilder sb = strWriter.GetStringBuilder();
sb.Insert(0, "Hey!! ");
Console.WriteLine("-> {0}", sb.ToString());
sb.Remove(0, "Hey!! ".Length);
Console.WriteLine("-> {0}", sb.ToString());
#endregion
// Read data from the StringWriter.
using (StringReader strReader = new StringReader(strWriter.ToString()))
{
string input = null;
while ((input = strReader.ReadLine()) != null)
{
Console.WriteLine(input);
}
}
}
5.BinaryWriter和BinaryReader类型
BinaryWriter和BinaryReader类型直接继承System.Object,可以让我们以简洁的二进制格式读写离散数据类型.
// Open a binary writer for a file.
FileInfo f = new FileInfo("BinFile.dat");
#region Move binary data into a file stream
using (BinaryWriter bw = new BinaryWriter(f.OpenWrite()))
{
// Print out the type of BaseStream.
// (System.IO.FileStream in this case).
Console.WriteLine("Base stream is: {0}", bw.BaseStream);
// Create some data to save in the file
double aDouble = 1234.67;
int anInt = 34567;
string aString = "A, B, C";
// Write the data
bw.Write(aDouble);
bw.Write(anInt);
bw.Write(aString);
}
#endregion
#region Read binary data in from stream
// Read the data as raw bytes
using (BinaryReader br = new BinaryReader(f.OpenRead()))
{
Console.WriteLine(br.ReadDouble());
Console.WriteLine(br.ReadInt32());
Console.WriteLine(br.ReadString());
}
#endregion
Console.ReadLine();
6.以编程方式(FileSystemWatcher)观察文件夹
// Establish the path to the directory to watch.
FileSystemWatcher watcher = new FileSystemWatcher();
try
{
watcher.Path = @"C:\MyFolder";
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
return;
}
#region Set up fliters / events.
// Set up the things to be on the lookout for.
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching the directory.
watcher.EnableRaisingEvents = true;
#endregion
// Wait for the user to quit the program.
Console.WriteLine(@"Press 'q' to quit app.");
while (Console.Read() != 'q') ;
}
#region Event Handlers
static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: {0} {1}!", e.FullPath, e.ChangeType);
}
static void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.
Console.WriteLine("File: {0} renamed to\n{1}", e.OldFullPath, e.FullPath);
}
#endregion
总结:Directory(Info)和File(Info)可以用来操作物理文件和目录.因为从Stream类型派生的类型操作的是原始直接流,所以常用读/写器(StreamWriter,StringWriter,BinaryWriter)来简化这个读写过程.最后,可以使用FileSystemWatcher来检测文件夹的变化.