1:写入一些内容到某个文件中,在另一个进程/线程/后续操作中要读取文件内容的时候报异常,提示 System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。
2:在对一个文件进行一些操作后(读/写),随后想追加依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。次问题与1相似。
3:对一个文件进行一些操作后,想删除文件,依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。
看到这些,有经验的同学应该就会说资源没被释放掉,但也存在如下可能性。我们对文件的操作非常频繁,所以写了特定的操作类/组件来维护文件之间的操作,知道特定的时刻才结束,常见的如日志,随着程序的启动便开始写日志,直到程序关闭。但此中也存在我们需要提供一个特殊的操作(读/写/删除)来操作文件,例如我们需要提供一个日志查看器来查看当前日志或所有日志,这时,便无可避免的发生了以上的问题。
复制代码 代码如下:
static void WriteFile(FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
{
Console.WriteLine("please input your content.");
var content = Console.ReadLine();
FileStream fs = new FileStream(FILEPATH, fileMode, fileAccess, fileShare);
var buffer = Encoding.Default.GetBytes(content);
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
}
首先,我声明了一个写文件方法,并调用它,它将我输入的内容写入指定的文件当中。
复制代码 代码如下:
WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read);
Console.ReadKey();
但是,在写文件操作结束之后,我并没有释放掉文件流的资源。所以,此时会对文件造成一个锁。我尝试在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这三个枚举身上,说不定就是它们搞的鬼。
FileMode
MSDN上的解释是指定操作系统打开文件的方式,我想这个应该不需要解释了,大家平时用得比较多了。MSDN的表格也很好的阐述了各个枚举值的作用,我就不在解释了。
FileAccess
定义用于文件读取、写入或读取/写入访问权限的常数。
这个枚举也用得比较多了,描述也很通俗易懂,我也不便再解释了。^_^!
FileShare
相信这个枚举类型大家会比较陌生,甚至有同学见都没见过(惭愧的是,我也是才认识它没多久),陌生归陌生,但它的作用力也是不可低估,只是.Net帮我们把它封装得比较好,以至于我们一度认为它不是什么重要角色。好吧,进入主题!
包含用于控制其他 FileStream 对象对同一文件可以具有的访问类型的常数。这句话是什么意思呢?说实话,我现在看句话还是觉得很纠结,相信很多同学看到也是一头雾水,没关系,我们先跳过!
看它的成员描述,和FileAccess很是相似,那我们就尝试着来揭开它暂时神秘的面纱吧!
FileShare.Read
从字面上的意思,我们可以理解为首先打开一个文件之后(资源未释放),我们可以再用只读的方式读取文件从而不会抛出文件无法访问的异常。利用刚才实现的方法,可以轻易的再完成这个实验:
复制代码 代码如下:
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.Write
结合Read的经验,字面上的意思应该可以理解为,只有在写文件时设置共享方式为Write,随后才能继续写入文件,否则会抛出异常。这里比较好玩的时,设置Write之后,万能的Window记事本也打不开文件了。
FileShare.ReadWrite
有了以上的经验,从字面上理解,可以认为这个ReadWrite一定是结合了Read和Write的特性。那到底它有什么用呢?上面我们知道,在读文件设置Read共享能继续读而不能写,在写文件时设置Write共享则能继续写而不能读,但是当我们设置了写共享后并想读取文件时怎么办?只能先释放资源再重新加载了吗?不需要,ReadWrite就是为此而生的。
复制代码 代码如下:
WriteFile(FileMode.Create, FileAccess.Write, FileShare.Read);
ReadFile(FileAccess.Read, FileShare.ReadWrite);
不过这里写文件的时候并不允许把共享设置成Write,否则读文件时用ReadWrite则无效(报异常),但都设置为ReadWrite可以。这一定,便可以解决很多日常开发中的烦恼。
FileShare.None/FileShare.Delete
有了上面的经验,相信这两个你也很容易的就理解了,None则为不允许后续有任何操作,而Delete则是允许你随后进行删除操作。
黑箱子里的内容
对于文件操作,我们平常使用的比较多的可能是以下几种:
复制代码 代码如下:
File.AppendAllText("......");
File.AppendAllLines(...);
File.AppendText(...);
FileStream fs = new FileStream(path, FileAccess.Write);
fs.Write(....);
实际上它们也是在内部初始化了FileMode/FileAccess/FileShare,例如File的静态方法最后都会生成一个Stream实例,其中便调用了私有方法
尾声
现在,我们明白了,其实/FileShare就是控制文件流的“访问权限”,当然,这仅仅是入门的文件操作,自己做了笔记,也希望能给大家带来帮助,高级篇园子里已经有不少前辈写了文件读写锁方面的文章,感兴趣的同学可有搜索一下,前去观摩!!
作者:空逸云
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]