FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)

摘要:
包含用于控制其他FileStream对象对同一文件可以具有的访问类型的常数。FileShare.Read从字面上的意思,我们可以理解为首先打开一个文件之后,我们可以再用只读的方式读取文件从而不会抛出文件无法访问的异常。FileShare.Write结合Read的经验,字面上的意思应该可以理解为,只有在写文件时设置共享方式为Write,随后才能继续写入文件,否则会抛出异常。

开发过程中,我们往往需要大量与文件交互,读文件,写文件已成家常便饭,本地运行完美,但一上到投产环境,往往会出现很多令人措手不及的意外,或开发中的烦恼,因此,我对普通的C#文件操作做了一次总结,问题大部分如下:

1:写入一些内容到某个文件中,在另一个进程/线程/后续操作中要读取文件内容的时候报异常,提示System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。

2:在对一个文件进行一些操作后(读/写),随后想追加依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。次问题与1相似。

3:对一个文件进行一些操作后,想删除文件,依然报System.IO.IOException: 文件“XXX”正由另一进程使用,因此该进程无法访问此文件。

看到这些,有经验的同学应该就会说资源没被释放掉,但也存在如下可能性。我们对文件的操作非常频繁,所以写了特定的操作类/组件来维护文件之间的操作,知道特定的时刻才结束,常见的如日志,随着程序的启动便开始写日志,直到程序关闭。但其中也存在我们需要提供一个特殊的操作(读/写/删除)来操作文件,例如我们需要提供一个日志查看器来查看当前日志或所有日志,这时,便无可避免的发生了以上的问题。

复制代码
staticvoidWriteFile(FileModefileMode,FileAccessfileAccess,FileSharefileShare)
{
Console.WriteLine("pleaseinputyourcontent.");
varcontent=Console.ReadLine();
FileStreamfs=newFileStream(FILEPATH,fileMode,fileAccess,fileShare);
varbuffer=Encoding.Default.GetBytes(content);
fs.Write(buffer,0,buffer.Length);
fs.Flush();
}
复制代码

首先,我声明了一个写文件方法,并调用它,它将我输入的内容写入指定的文件当中。

WriteFile(FileMode.Create,FileAccess.Write,FileShare.Read);
Console.ReadKey();

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第3张FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第4张

但是,在写文件操作结束之后,我并没有释放掉文件流的资源。所以,此时会对文件造成一个锁。我尝试在windows中删除它。

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第5张

很明显我无法删除掉这个文件,接下来,我尝试读取它。

复制代码
staticvoidReadFile(FileAccessfileAccess,FileSharefileShare)
{
FileStreamfs=newFileStream(FILEPATH,FileMode.Open,fileAccess,fileShare);
varbuffer=newbyte[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);

一切都很简单,访问模式为只读,这样应该就不会与上面的写锁进行冲突!

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第8张

但是,结果并非我们所预想的那样,为什么会提示无法访问?回想一下,在前面,我用windows的记事本打开了这个文件,并没有提示说文件被锁定,我也的确能访问,那为何到了程序里就无法访问了呢?或许,我们应该把重点放在FileModeFileAccessFileShare这三个枚举身上,说不定就是它们搞的鬼。

FileMode

MSDN上的解释是指定操作系统打开文件的方式,我想这个应该不需要解释了,大家平时用得比较多了。MSDN的表格也很好的阐述了各个枚举值的作用,我就不在解释了。

FileAccess

定义用于文件读取、写入或读取/写入访问权限的常数。

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第9张

这个枚举也用得比较多了,描述也很通俗易懂,我也不便再解释了。^_^!

FileShare

相信这个枚举类型大家会比较陌生,甚至有同学见都没见过(惭愧的是,我也是才认识它没多久),陌生归陌生,但它的作用力也是不可低估,只是.Net帮我们把它封装得比较好,以至于我们一度认为它不是什么重要角色。好吧,进入主题!

包含用于控制其他FileStream对象对同一文件可以具有的访问类型的常数。这句话是什么意思呢?说实话,我现在看句话还是觉得很纠结,相信很多同学看到也是一头雾水,没关系,我们先跳过!

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第10张

看它的成员描述,和FileAccess很是相似,那我们就尝试着来揭开它暂时神秘的面纱吧!

FileShare.Read

从字面上的意思,我们可以理解为首先打开一个文件之后(资源未释放),我们可以再用只读的方式读取文件从而不会抛出文件无法访问的异常。利用刚才实现的方法,可以轻易的再完成这个实验:

WriteFile(FileMode.Create,FileAccess.Write,FileShare.Read);
ReadFile(FileAccess.Read,FileShare.Read);

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第11张

这是什么回事?不是都设置成已读了吗?或许只能在读文件的时候才能设置为只读共享。我们再尝试一下:

ReadFile(FileAccess.Read,FileShare.Read);
ReadFile(FileAccess.Read,FileShare.Read);

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第12张

这次的确是能在第一次没释放资源时再读,那我们再试试能否在设置只读共享后写文件:

ReadFile(FileAccess.Read,FileShare.Read);
WriteFile(FileMode.Create,FileAccess.Write,FileShare.Read);

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第13张

首先正确的读出了文件的内容,但当我尝试写入一些内容的时候却又报错了。那么,根据以上的实验,就可以得知这个只读的共享只有是在连续读取文件才有效!

FileShare.Write

结合Read的经验,字面上的意思应该可以理解为,只有在写文件时设置共享方式为Write,随后才能继续写入文件,否则会抛出异常。这里比较好玩的时,设置Write之后,万能的Window记事本也打不开文件了。

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第14张

FileShare.ReadWrite

有了以上的经验,从字面上理解,可以认为这个ReadWrite一定是结合了Read和Write的特性。那到底它有什么用呢?上面我们知道,在读文件设置Read共享能继续读而不能写,在写文件时设置Write共享则能继续写而不能读,但是当我们设置了写共享后并想读取文件时怎么办?只能先释放资源再重新加载了吗?不需要,ReadWrite就是为此而生的。

WriteFile(FileMode.Create,FileAccess.Write,FileShare.Read);
ReadFile(FileAccess.Read,FileShare.ReadWrite);

FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)第15张

不过这里写文件的时候并不允许把共享设置成Write,否则读文件时用ReadWrite则无效(报异常),但都设置为ReadWrite可以。这一定,便可以解决很多日常开发中的烦恼。

FileShare.None/FileShare.Delete

有了上面的经验,相信这两个你也很容易的就理解了,None则为不允许后续有任何操作,而Delete则是允许你随后进行删除操作。

原文链接FileShare枚举的使用(文件读写锁)

免责声明:文章转载自《FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇STM32——timermodelsim脚本文件的编写下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

第三章 RNA测序

  RNA测序(RNA Sequencing,简称RNA-Seq,也被称为全转录物组鸟枪法测序Whole Transcriptome Shotgun Sequencing,简称WTSS),是基于二代测序技术研究转录组学的方法,可以快速获取给定时刻的一个基因组中RNA的种类和数量。 RNA-Seq有助于查看基因的不同转录本、转录后修饰、基因融合、突变/S...

[转]慎用InputStream的read()方法

InputStream此抽象类是表示字节输入流的所有类的超类。 我们从输入流中读取数据最常用的方法基本上就是如下3个read()方法了: 1、read()方法,这个方法从输入流中读取数据的下一个字节。返回 0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回值-1。 2、read(byte[]b,intoff,intlen)方法...

socket 中read返回0的情况

当client,调用read(socketfd,buffer,n)时,返回0的情况: 1、server端调用了close(soketfd)函数 2、server调用了close(fd,SHUT_WR),关闭server端的写连接,半关闭 关于close 和shutdown的过程 一.void close(fd):close发送的是FIN分节(不一定是发送...

深入理解读写锁—ReadWriteLock源码分析

转载:https://blog.csdn.net/qq_19431333/article/details/70568478 ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。 所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所...

java基础系列--SecurityManager入门(转)

转载作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/yiwangzhibujian/p/6207212.html 一、文章的目的   这是一篇对Java安全管理器入门的文章,目的是简单了解什么是SecurityManager,对管理器进行简单配置,解决简单问题。   比如在阅读源码的时候,发现这样的代码,想了解是做什么的:...

PCIe Max_Payload_Size 和 Max_Read_Request_Size

最近PCIe在SSDFans上镜率挺高,那我们来聊两句MAX_READ_REQUEST_SIZE 和MAX_PAYLOAD_SIZE。 这两个东西都在PCIe Capability Structure 08h (Device Control Register)里 Maximum Payload Size (简称MPS) 控制一个TLP可以传输的最大数据长...