.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 ...
随机推荐
- Python中关于进度条的6个实用技巧
1 简介 费老师我在几年前写过的一篇文章(https://www.cnblogs.com/feffery/p/13392024.html)中,介绍过tqdm这个在当下Python圈子中已然非常流行的进 ...
- SpringBoot利用自定义注解实现通用的JWT校验方案
利用注解开发一个通用的JWT前置校验功能 设计的预期: 系统中并不是所有的应用都需要JWT前置校验,这就需要额外设计一个注解Annotation来标识这个方法需要JWT前置校验.例如: @GetMap ...
- webpack打包学习
从上图我们可以看出,webpack 可以将多种静态资源 js.css.sass文件等转换成一个静态文件,以此可以减少页面的请求,从而提高浏览器响应速度 1.安装开发依赖包 npm install we ...
- Rb(redis blaster),一个为 redis 实现 non-replicated 分片的 python 库
Rb,redis blaster,是一个为 redis 实现非复制分片(non-replicated sharding)的库.它在 python redis 之上实现了一个自定义路由系统,允许您自动定 ...
- Python自动批量修改服务器密码
工作中,我们经常会定期更换服务器密码,如果手动去修改,不仅费时,而且容易出错.下面提供了一种思路,可以实现批量.自动修改服务器密码. 大致思路:首先,为每一台服务器设定一个唯一标识:其次,将每台服务器 ...
- 帝国CMS如何互相转移分表之间的数据
最近发现帝国CMS文章数据添加太多到某一张分表中了,如图 这是极其不合理的,需要优化下,所以这篇文章要告诉大家的也就是如何互相转移分表之间的数据. 我现在要将:phome_ecms_news_data ...
- C++五子棋(三)——判断鼠标有效点击
分析 在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下--棋盘线的交点处. 功能实现 创建数据类型 创建头文件chessData.h和源文件chessData. ...
- 计算机编码规则之:Base64编码
目录 简介 Base64和它的编码原理 Base64的变体 Base64的编码细节 总结 简介 我们知道计算机中的文件可以分为两种,一种是人肉眼可读的文本类文件,一种是肉眼不可读的二进制文件.一般来说 ...
- OpenHarmony标准设备应用开发(三)——分布式数据管理
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 邢碌 上一章,我们通过分布式音乐播放器.分布式炸弹.分布式购物车,带大家讲解了 OpenAtom OpenHarmon ...
- Selenium3自动化测试【27】Frame的操作
本篇文章内容摘要 " 讲解Python3+Selenium3如何处理Frame窗体" 同步视频知识与系列知识内容,可关注:[公众号]:柒哥测试:[WX]:Lee-890;[视频号] ...