一个平凡菜鸟的C#琐碎总结 ----- 文件操作(二)

四、文件监视类:FileSystemWatcher

侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。可借助FileSystemWatcher会更简单些。

1、属性:

(1)Path——这个属性告诉FileSystemWatcher它需要监控哪条路径。例如,如果我们将这个属性设为“C:\test”,对象就监控test目录下所有文件发生的所有改变(包括删除,修改,创建,重命名)。

(2)IncludeSubDirectories——这个属性说明FileSystemWatcher对象是否应该监控子目录中(所有文件)发生的改变。

(3)Filter——这个属性允许你过滤掉某些类型的文件发生的变化。例如,如果我们只希望在TXT文件被修改/新建/删除时提交通知,可以将这个属性设为“*txt”。在处理高流量或大型目录时,使用这个属性非常方便。

(4)NotifyFilter——获取或设置要监视的更改类型。可以进一步的过滤要监控的更改类型:如watcher.NotifyFilter= NotifyFilters.LastAccess | NotifyFilters.LastWrite

| NotifyFilters.FileName | NotifyFilters.DirectoryName;

2、事件:

(1)Changed——当被监控的目录中有一个文件被修改时,就提交这个事件。值得注意的是,这个事件可能会被提交多次,即使文件的内容仅仅发生一项改变。这是由于在保存文件时,文件的其它属性也发生了改变。

(2)Created——当被监控的目录新建一个文件时,就提交这个事件。如果你计划用这个事件移动新建的事件,你必须在事件处理器中写入一些错误处理代码,它能处理当前文件被其它进程使用的情况。之所以要这样做,是因为Created事件可能在建立文件的进程释放文件之前就被提交。如果你没有准备正确处理这种情况的代码,就可能出现异常。

(3)Deleted——当被监控的目录中有一个文件被删除,就提交这个事件。

(4)Renamed——当被监控的目录中有一个文件被重命名,就提交这个事件。

注:如果你没有将EnableRaisingEvents设为真,系统不会提交任何一个事件。如果有时FileSystemWatcher对象似乎无法工作,请首先检查EnableRaisingEvents,确保它被设为真。

3、事件处理

当FileSystemWatcher调用一个事件处理器时,它包含两个自变量——一个叫做“sender”的对象和一个叫做“e”的FileSystemEventArgs对象。我们感兴趣的自变量为FileSystemEventArgs自变量。这个对象中包含有提交事件的原因。以下是FileSystemEventArgs对象的一些属性:

属性:

(1)Name——这个属性中使事件被提交的文件的名称。其中并不包含文件的路径——只包含使用事件被提交的文件或目录名称。

(2)ChangeType——这是一个WatcherChangeTypes,它指出要提交哪个类型的事件。其有效值包括:Changed,Created,Deleted,Renamed

(3)FullPath——这个属性中包含使事件被提交的文件的完整路径,包括文件名和目录名。

注意:FileSystemEventArgs对象是监控文件夹下有文件创建、删除、修改时的自变量,如果是重命名的话为RenamedEventArgs对象此时除了FileSystemEventArgs对象的属性值,多了一个OldFullPath,为重命名之前的文件名。

五、文件的读取和写入文件

1、流的概念:在.net FrameWork中进行的所有的输入输出工作都需要使用流.流是串行化设备的抽象表示.串行化设备可以以线性方式存储数据,并可以以同样的方式访问:一次访问一个字节.此设备可以是磁盘文件,打印机,内存位置或任何其他支持以线性方式读写的对象.通过使用设备抽象,就可以隐藏流的基础性的目标或源.这种抽象的级别使得代码可以重用,允许我们编写更通用的程序.因此,当程序从文件输入流或网络输入流读取数据时,就可以转换并重用类似的代码.而且,通过使用流,我们还可以忽略每一种设备的物理机制.因此为了从文件流中读取文件,我们无须担心磁盘开销或内存分配等问题

C# 中Stream类是所有流的抽象基类,它可以为流提供一般性视图,从而使得开发人员不需要了解I/O设备的具体细节。与流相关的操作包括以下3个基本操作。

读取流:即读取流中的内容。

写入流:即将指定的内容写入到流中。

流支持查找:即可以查找或设置流的当前位置。

与流相关的、最为常用的类包括Stream类、FileStream类(文件流,常用于操作文件)、MemoryStream类(内存流,常用来操作内存中的数据)和BufferedStream类(缓存流,用来操作缓存中的数据)。其中Stream类为抽象类,FileStream类、MemoryStream类和BufferedStream类从直接继承于Stream类,它们是实体类。

2、使用FileStream类管理文件数据

先看几个例子:

(1)    使用FileStream流写入文本文件:

static void  Main(string[] args)

{

       string str = "helloworld";

       string strPath= @"D:\test.txt";

       FileInfo  fileStr = new FileInfo(strPath);

       byte[] strWrite= new UTF8Encoding(true).GetBytes(str);

FileStream StrStream=fileStr.Create();

StrStream.Write(strWrite,0, strWrite.Length);

Console.WriteLine("写入成功!");

StrStream.Close();

}

(2)使用MemoryStream类管理内存数据

    staticvoid Main(string[]args)

    {

string str = "你好!"

      byte[]  MermoryWrite = newUTF8Encoding(true).GetBytes(str);

      //在内存中申请适合的空间

      MemoryStream  ms = new MemoryStream(MermoryWrite.Length);

      //写入内存缓冲区

      ms.Write(MermoryWrite, 0,MermoryWrite.Length);

      //打印出当前流的位置

      Console.WriteLine(ms.Position);

      //清空缓冲区

      ms.Flush();

      //seek属于定位指针函数,第一个参数它是相对于第二个参数的位置,也相当于偏移量。第二个参数是它用作查找参考点。

      //返回值:流内的新位置,通过将初始参考点和偏移量合并计算而得。

      ms.Seek(0, SeekOrigin.Begin);

      byte[] temp = new byte[MermoryWrite.Length];

      // 从当前流中读取字节块并将数据写入 buffer 中。返回写入缓冲区中的总字节数。

      ms.Read(temp, 0, (int)ms.Length);

      Console.WriteLine(new UTF8Encoding(true).GetChars(temp));

        }      

}

(2)    使用BufferedStream来提高流的性能

static void Main(string[] args)

        {

            string  str = "你好!";

            string   strPath = @"D:\test.txt";

            FileInfo  fileStr = new FileInfo(strPath);

            byte[]   strWrite = new UTF8Encoding(true).GetBytes(str);

            FileStream   StrStream = fileStr.Create();

            //实例化缓冲区

            BufferedStream   bufferStr = new BufferedStream(StrStream);

            //向缓冲区中写入流

           bufferStr.Write(strWrite, 0, strWrite.Length);

            bufferStr.Close();

            StrStream.Close();

            Console.WriteLine("写入成功!");   

        }

3、管理应用程序数据

(1)    管理文本数据用StreamReader和StreamWriter,它们继承与抽象类TextReader类和TextWriter类,这点注意不要用错了。

如:读取D:\test.txt文件

static void Main(string[] args)

        {

            string strPath= @"D:\test.txt";          

            //写入文件

            StreamWriter  sw=new StreamWriter(File.Open(strPath,FileMode.Append));

            sw.WriteLine(DateTime.Now.ToString());

            //注意清空缓冲区和关闭流对象

            sw.Flush();

            sw.Close();

            //从文件中读取数据

            StreamReader   sr=new StreamReader(File.Open(strPath,FileMode.Open));

            Console.WriteLine(sr.ReadToEnd());

}

(2)    管理字符串数据用StringReader类和StringWriter类,注意用到StringBuilder

        static void Main(string[]args)

        {          

            //写入字符串

            StringBuilder   sb = new StringBuilder();

            StringWriter    sw = new StringWriter(sb);      

            sw.WriteLine(DateTime.Now.ToString());

            //注意清空缓冲区和关闭流对象

            sw.Flush();

            sw.Close();

            //从文件中读取数据

            StringReader   sr = new StringReader(sb.ToString());

            Console.WriteLine(sr.ReadToEnd());

}

(3)    管理二进制文件用BinaryReader类和BinaryWriter类,注意需要一个stream对象

        static void Main(string[] args)

        {

            string strPath= @"D:\test.dat";          

            //写入二进制文件        

            BinaryWriter bw=new BinaryWriter(File.Open(strPath,FileMode.OpenOrCreate));

            bw.Write(true);;

            bw.Write('A');

            //注意清空缓冲区和关闭流对象

            bw.Flush();

            bw.Close();

            //从文件中读取数据

            BinaryReaderbr = new BinaryReader(File.Open(strPath, FileMode.Open));

            Console.WriteLine(br.ReadBoolean());           

            Console.WriteLine(br.ReadChar());           

}

注:以上这些类都是继承于Stream类的

(4).NET Framework的字符编码类:在这里不再赘述,可以查msdn(http://msdn.microsoft.com/zh-cn/ms404377

(5)扩展下,高效处理字符串

看一下如下代码:

    string str="";

    for(int i = 0; i < 1000; i++)

     {

       str += i.ToString();     

  }

字符串是引用类型,这样将会有999个空间是浪费的,所以为了提高效率引用StringBuilder,而不仅仅是合并。

以上代码可以改为:

    StringBuilder str = newStringBuilder();

    for(int i = 0; i < 1000; i++)

     {

        str.Append(i.ToString());     

  }

这样效率就会大大提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值