asp.net 细说文件读写操作(读写锁) |
本文标签:文件读写 问题大部分如下: 1:写入一些内容到某个文件中,在另一个进程/线程/后续操作中要读取文件内容的时候报异常,提示 System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件 。 2:在对一个文件进行一些操作后(读/写),随后想追加依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件 。次问题与1相似 。 3:对一个文件进行一些操作后,想删除文件,依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件 。 看到这些,有经验的同学应该就会说资源没被释放掉,但也存在如下可能性 。我们对文件的操作非常频繁,所以写了特定的操作类/组件来维护文件之间的操作,知道特定的时刻才结束,常见的如日志,随着程序的启动便开始写日志,直到程序关闭 。但此中也存在我们需要提供一个特殊的操作(读/写/删除)来操作文件,例如我们需要提供一个日志查看器来查看当前日志或所有日志,这时,便无可避免的发生了以上的问题 。 但是,在写文件操作结束之后,我并没有释放掉文件流的资源 。所以,此时会对文件造成一个锁 。我尝试在windows中删除它 。 很明显我无法删除掉这个文件,接下来,我尝试读取它 。 复制代码 代码如下: static void ReadFile(FileAccess fileAccess, FileShare fileShare) { FileStream fs = new FileStream(FILEPATH, FileMode.Open, fileAccess, fileShare); var buffer = new byte[fs.Length]; fs.Position = 0; fs.Read(buffer, 0, buffer.Length); Console.WriteLine(Encoding.Default.GetString(buffer)); } 我实现了一个读文件方法,并调用了它 。 复制代码 代码如下: WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read); ReadFile(FileAccess.Read, FileShare.Read); 一切都很简单,访问模式为只读,这样应该就不会与上面的写锁进行冲突! 但是,结果并非我们所预想的那样,为什么会提示无法访问?回想一下,在前面,我用windows的记事本打开了这个文件,并没有提示说文件被锁定,我也的确能访问,那为何到了程序里就无法访问了呢?或许,我们应该把重点放在FileMode,FileAccess,FileShare这三个枚举身上,说不定就是它们搞的鬼 。 这个枚举也用得比较多了,描述也很通俗易懂,我也不便再解释了 。^_^!
复制代码 代码如下: WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read); ReadFile(FileAccess.Read, FileShare.Read); 这是什么回事?不是都设置成已读了吗?或许只能在读文件的时候才能设置为只读共享 。我们再尝试一下: 复制代码 代码如下: ReadFile(FileAccess.Read, FileShare.Read); ReadFile(FileAccess.Read, FileShare.Read); 这次的确是能在第一次没释放资源时再读,那我们再试试能否在设置只读共享后写文件: 复制代码 代码如下: ReadFile(FileAccess.Read, FileShare.Read); WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read); 首先正确的读出了文件的内容,但当我尝试写入一些内容的时候却又报错了 。那么,根据以上的实验,就可以得知这个只读的共享只有是在连续读取文件才有效! FileShare.ReadWrite 复制代码 代码如下: WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read); ReadFile(FileAccess.Read, FileShare.ReadWrite); 不过这里写文件的时候并不允许把共享设置成Write,否则读文件时用ReadWrite则无效(报异常),但都设置为ReadWrite可以 。这一定,便可以解决很多日常开发中的烦恼 。 复制代码 代码如下: File.AppendAllText("......"); File.AppendAllLines(...); File.AppendText(...); FileStream fs = new FileStream(path, FileAccess.Write); fs.Write(....); 实际上它们也是在内部初始化了FileMode/FileAccess/FileShare,例如File的静态方法最后都会生成一个Stream实例,其中便调用了私有方法 尾声 |