.NET中检测文件是否被其他进程占用
更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月2日。
一、检测文件是否被进程占用的几种方式
在.NET中主要有以下方式进行检测文件是否被进程占用的几种方式:
- 通过直接打开文件等操作,根据是否弹出异常来判断是否被其他进程占用。
- 使用互操作去检测文件是否被其他进程占用。
二、使用异常来测试是否被其他进程占用
直接打开文件进行读,因为文件不完整,所以会抛出异常。通过goto实现一直监听文件是否复制完成。因为异常的性能相比正常代码性能非常低,并且使用异常来实现代码逻辑也非常不合适,所以建议使用另一种方法进行实现同样的功能。
代码实例:
using System;
using System.IO;
using System.Linq;
using System.Threading;
namespace PandaTestClass
{
class Program
{
static void Main(string[] args)
{
//新建文件监听器
FileSystemWatcher watcher = new FileSystemWatcher();
//====配置文件监听器=====
//监听的目录
string monitoredPath = @"E:/";
//监听的文件类型
string monitoredFileType = "*.txt|*.cs";
//监听的修改的具体操作类型
NotifyFilters notifyFilters = NotifyFilters.FileName
| NotifyFilters.Size
| NotifyFilters.LastWrite;
//设置参数
watcher.Path = monitoredPath;
monitoredFileType.Split("|")
.ToList()
.ForEach(elem => watcher.Filters.Add(elem));
watcher.NotifyFilter = notifyFilters;
//====配置文件监听器=====
//====绑定事件处理函数====
//绑定文件修改事件处理函数
watcher.Changed += (object sender, FileSystemEventArgs args) => {
Console.WriteLine("文件修改啦");
Console.WriteLine($"被修改的文件是{args.Name}");
Console.WriteLine($"被修改的文件文件路径是{args.FullPath}");
Console.WriteLine($"修改的类型{args.ChangeType.ToString()}");
//====检测创建后是否可用(比如:是否复制完成)====
//先检测文件是否存在
FileInfo fileInfo = new(args.FullPath);
if (!fileInfo.Exists)
{
return;
}
//检测文件是否复制完成
NotComplate: try
{
File.OpenRead(fileInfo.FullName);
}
catch(Exception e)
{
Console.WriteLine("文件还未复制完成");
Thread.Sleep(TimeSpan.FromSeconds(3));
goto NotComplate;
}
//可以对文件进行操作
Console.WriteLine("可以对文件进行操作了");
//====检测创建后是否可用(比如:是否复制完成)====
//对文件具体操作的代码
};
//====绑定事件处理函数====
//开启监听
watcher.EnableRaisingEvents = true;
//等待用户关闭监听
while (true)
{
Console.WriteLine("如需关闭监听,请按Y:");
if ((Console.ReadKey()).Key == ConsoleKey.Y)
{
//释放监听器
watcher.Dispose();
return;
}
}
}
}
}
三、通过互操作检测文件是否被其他进程占用
首先,需要在代码中引入互操作函数和常量。
打开文件用于测试文件是否可用。
[DllImport("kernel32.dll")]
public static extern IntPtr _lopen(string lpPathName, int iReadWrite);
关闭句柄,用于关闭已打开的文件句柄。
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
文件打开的模式-读写
public const int OF_READWRITE = 2;
文件打开的模式-共享读写
public const int OF_SHARE_DENY_NONE = 0x40;
文件打开错误标志位,用于判断文件打开后的状态判断
public static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
在每次进行文件操作前,对文件进行测试是否可以访问
//检测文件是被其他进程占用
IntPtr vHandle = _lopen(args.FullPath, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
Console.WriteLine("文件被其他进程占用,不可以操作");
return;
}
//释放句柄
CloseHandle(vHandle);
//文件可以操作了
代码实例:监听文件的操作,如果文件复制完成了再进行操作
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace PandaTestClass
{
class Program
{
/// <summary>
/// 打开文件,用于测试文件是否可用
/// </summary>
/// <param name="lpPathName"></param>
/// <param name="iReadWrite"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern IntPtr _lopen(string lpPathName, int iReadWrite);
/// <summary>
/// 关闭句柄
/// </summary>
/// <param name="hObject"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
/// <summary>
/// 文件打开的模式,读写权限
/// </summary>
public const int OF_READWRITE = 2;
/// <summary>
/// 文件打开的模式,进程间共享读写
/// </summary>
public const int OF_SHARE_DENY_NONE = 0x40;
/// <summary>
/// 文件打开错误标志位
/// </summary>
public static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
static void Main(string[] args)
{
//新建文件监听器
FileSystemWatcher watcher = new FileSystemWatcher();
//====配置文件监听器=====
//监听的目录
string monitoredPath = @"E:/";
//监听的文件类型
string monitoredFileType = "*.txt|*.cs";
//监听的修改的具体操作类型
NotifyFilters notifyFilters = NotifyFilters.FileName
| NotifyFilters.Size
| NotifyFilters.LastWrite;
//设置参数
watcher.Path = monitoredPath;
monitoredFileType.Split("|")
.ToList()
.ForEach(elem => watcher.Filters.Add(elem));
watcher.NotifyFilter = notifyFilters;
//====配置文件监听器=====
//====绑定事件处理函数====
//绑定文件修改事件处理函数
watcher.Changed += (object sender, FileSystemEventArgs args) => {
Console.WriteLine("文件修改啦");
Console.WriteLine($"被修改的文件是{args.Name}");
Console.WriteLine($"被修改的文件文件路径是{args.FullPath}");
Console.WriteLine($"修改的类型{args.ChangeType.ToString()}");
//====检测创建后是否可用(比如:是否复制完成)====
//先检测文件是否存在
FileInfo fileInfo = new(args.FullPath);
if (!fileInfo.Exists)
{
return;
}
//检测文件是否复制完成
IntPtr vHandle = _lopen(args.FullPath, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
Console.WriteLine("文件还未复制完成");
return;
}
//释放句柄
CloseHandle(vHandle);
//可以对文件进行操作
Console.WriteLine("可以对文件进行操作了");
//====检测创建后是否可用(比如:是否复制完成)====
//对文件具体操作的代码
};
//====绑定事件处理函数====
//开启监听
watcher.EnableRaisingEvents = true;
//等待用户关闭监听
while (true)
{
Console.WriteLine("如需关闭监听,请按Y:");
if ((Console.ReadKey()).Key == ConsoleKey.Y)
{
//释放监听器
watcher.Dispose();
return;
}
}
}
}
}
.NET中检测文件是否被其他进程占用的更多相关文章
- 使用c#检测文件正在被那个进程占用 判断文件是否被占用的两种方法
C# 判断文件是否被占用的三种方法 using System.IO; using System.Runtime.InteropServices; [DllImport("kernel32.d ...
- 使用c#检测文件正在被那个进程占用
要检测文件被那个进程占用,需要使用微软提供的工具Handle.exe,这里有微软提供的下载 我们可以在c#中调用Handle.exe 来检测到底哪个进程占用了文件 string fileName = ...
- 在.NetCore中使用Myrmec检测文件真实格式
Myrmec 是什么? Myrmec 是一个用于检测文件格式的库,Myrmec不同于其它库或者手写检测代码,Myrmec不依赖文件扩展名(在实际使用中,你的用户很可能使用虚假的扩展名欺骗你的应用程序) ...
- sqlserver检测死锁;杀死锁和进程;查看锁信息
http://blog.sina.com.cn/s/blog_9dcdd2020101nf4v.html sqlserver检测死锁;杀死锁和进程;查看锁信息 ( ::)转载▼ 标签: sql 检测死 ...
- 如何在 Linux 中查看进程占用的端口号【转】
对于 Linux 系统管理员来说,清楚某个服务是否正确地绑定或监听某个端口,是至关重要的.如果你需要处理端口相关的问题,这篇文章可能会对你有用. 端口是 Linux 系统上特定进程之间逻辑连接的标识, ...
- C++之检测文件结尾
当使用文件作为输入流时,为了确保适时的结束文件读取操作,程序要靠检查文件尾来判断该何时停止读取.常用的检查文件尾方法有两种: 两种方式均已将 fin 与文件关联,即 均已声明 fin 输入流,并已调用 ...
- linux中Makefile文件相关内容
第一章.概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional(专业)的程序员,m ...
- 关于Python中的文件操作(转)
总是记不住API.昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Pyth ...
- 从客户端中检测到有潜在危险的 request.form值[解决方法]
当页面编辑或运行提交时,出现“从客户端中检测到有潜在危险的request.form值”问题,该怎么办呢?如下图所示: 下面博主汇总出现这种错误的几种解决方法:问题原因:由于在asp.net中,Requ ...
随机推荐
- Jenkins忘记admin密码
我的解决方法: 1.找到Jenkins的comfig.xml配置文件 可以使用find或者locate来查找. 2.备份原来的配置文件,cp备份. 3.修改配置文件: 因为在comfig.xml中ad ...
- I/O 引脚
我们以网卡举例 引脚,芯片,pcb板之间的关系非常紧密 1.引脚,又叫管脚,英文叫Pin. 就是从集成电路(芯片)内部电路引出与外围电路的接线,所有的引脚就构成了这块芯片的接口.引线末端的一段,通过软 ...
- [已解决] 含gorm、sqlite3包的go程序构建失败 C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
gorm官方文档教程实例,构建出现错误.C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit st ...
- uniapp报错:Browserslist: caniuse-lite is outdated. Please run next command `npm update`
uni-app的编译器是基于npm的,依赖了众多包括mpvue.webpack在内的npm库,这些库又引用了一个三方库caniuser-lite.caniuser-lite这个库的代码里有个浏览器兼容 ...
- 茴香豆的“茴”有四种写法,Python的格式化字符串也有
茴香豆的"茴"有四种写法,Python的格式化字符串也有 茴香豆的"茴"有四种写法,Python的格式化字符串也有 被低估的断言 多一个逗号,少一点糟心事 上下 ...
- 数据传输POST心法分享,做前端的你还解决不了这个bug?
背景 随时随地给大家提供技术支持的葡萄又来了.这次的事情是这样的,提供demo属于是常规操作,但是前两天客户突然反馈压缩传输模块抛出异常,具体情况是压缩内容传输到服务端后无法解压. 由于代码没有发生任 ...
- XCTF练习题---MISC---What-is-this
XCTF练习题---MISC---What-is-this flag:AZADI TOWER 解题步骤: 1.观察题目,下载附件 2.下载后发现是个压缩包,文件内容不清楚,试试改为压缩包看看效果,发现 ...
- Protobuf在Python中的应用(序列化数据)
1.了解Protobuf Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单.您可以定义数据的结构化,然后可 ...
- SpringBoot项目刚刚创建就报异常,Failed to configure a DataSource: 'url' attribute is not specified and no embedded 的解决办法
错误信息: Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedde ...
- vue - vue基础/vue核心内容(2)
今天的内容书接上回,同样是vue的核心基础部分,今天偏向于理论性,特别是vue对于数据对象的监测那一块,刚开始琢磨了半天,这股劲一过,现在好理解多了 10.watch和computed对比 计算属性案 ...