更新记录

本文迁移自Panda666原博客,原发布时间:2021年7月2日。

一、检测文件是否被进程占用的几种方式

在.NET中主要有以下方式进行检测文件是否被进程占用的几种方式:

  1. 通过直接打开文件等操作,根据是否弹出异常来判断是否被其他进程占用。
  2. 使用互操作去检测文件是否被其他进程占用。

二、使用异常来测试是否被其他进程占用

直接打开文件进行读,因为文件不完整,所以会抛出异常。通过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中检测文件是否被其他进程占用的更多相关文章

  1. 使用c#检测文件正在被那个进程占用 判断文件是否被占用的两种方法

    C# 判断文件是否被占用的三种方法 using System.IO; using System.Runtime.InteropServices; [DllImport("kernel32.d ...

  2. 使用c#检测文件正在被那个进程占用

    要检测文件被那个进程占用,需要使用微软提供的工具Handle.exe,这里有微软提供的下载 我们可以在c#中调用Handle.exe 来检测到底哪个进程占用了文件 string fileName = ...

  3. 在.NetCore中使用Myrmec检测文件真实格式

    Myrmec 是什么? Myrmec 是一个用于检测文件格式的库,Myrmec不同于其它库或者手写检测代码,Myrmec不依赖文件扩展名(在实际使用中,你的用户很可能使用虚假的扩展名欺骗你的应用程序) ...

  4. sqlserver检测死锁;杀死锁和进程;查看锁信息

    http://blog.sina.com.cn/s/blog_9dcdd2020101nf4v.html sqlserver检测死锁;杀死锁和进程;查看锁信息 ( ::)转载▼ 标签: sql 检测死 ...

  5. 如何在 Linux 中查看进程占用的端口号【转】

    对于 Linux 系统管理员来说,清楚某个服务是否正确地绑定或监听某个端口,是至关重要的.如果你需要处理端口相关的问题,这篇文章可能会对你有用. 端口是 Linux 系统上特定进程之间逻辑连接的标识, ...

  6. C++之检测文件结尾

    当使用文件作为输入流时,为了确保适时的结束文件读取操作,程序要靠检查文件尾来判断该何时停止读取.常用的检查文件尾方法有两种: 两种方式均已将 fin 与文件关联,即 均已声明 fin 输入流,并已调用 ...

  7. linux中Makefile文件相关内容

    第一章.概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional(专业)的程序员,m ...

  8. 关于Python中的文件操作(转)

    总是记不住API.昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Pyth ...

  9. 从客户端中检测到有潜在危险的 request.form值[解决方法]

    当页面编辑或运行提交时,出现“从客户端中检测到有潜在危险的request.form值”问题,该怎么办呢?如下图所示: 下面博主汇总出现这种错误的几种解决方法:问题原因:由于在asp.net中,Requ ...

随机推荐

  1. C#多线程下的调优

    一.原子操作 先看一段问题代码 /// <summary> /// 获取自增 /// </summary> public static void GetIncrement() ...

  2. Docker操作容器2

    Docker操作容器1:https://blog.csdn.net/Kevinnsm/article/details/ 1.如何更改docker容器中的配置文件(如nginx容器中的nginx.con ...

  3. MySQL高级以及锁机制

    MySQL高级 推荐阅读: 锁:https://www.cnblogs.com/zwtblog/tag/锁/ 数据库:https://www.cnblogs.com/zwtblog/tag/数据库/ ...

  4. 查看k8s的yaml里面反馈的错误,不仅仅是通过日志来查看错误

    使用:kubectl describe pod......例如: kubectl describe pod api-55f5d8d49d-kzmcj ///////////////////////// ...

  5. 直接远程下载或上传文件到linux系统中的简单办法

    如果执行sz 或者rz 没有这个命令,则安装lrzsz包执行:yum install lrzsz 等待安装完毕,然后一直输入Y即可. sz:将选定的文件发送(send)到本地机器 -a 以文本方式传输 ...

  6. git版本时提示openssl ssl_read

    1.右击git bash here 2.执行 git config --global http.sslVerify "false"

  7. WorkCount

    此项目码云链接 软件测试方法和技术第二次作业 1 作业内容 根据WordCount的需求描述,先编程实现,再编写单元测试,最后撰写博客.至少完成需求中的基本功能. 2 WordCount需求说明 Wo ...

  8. 攻防世界-MISC:ext3

    这是攻防世界新手练习区的第九题,题目如下: 点击下载附件1,通过题目描述可知这是一个Linux系统光盘,用010editor打开,搜索flag,发现存在flag.txt文件 将该文件解压,找到flag ...

  9. Java 16 新特性:instanceof增强

    instanceof这个关键词,主要用来判断某个对象是不是某个类的实例. 比如,有时候我们要处理一个类似这样的数据集: Map<String, Object> data = new Has ...

  10. kNN-预测

    现在进行第五步,对数据进行预测 那么要做的的是从数据集里面拿出一部分作为要预测的,剩下的去比较,书上使用的是10% # 对之前做好的kNN算法进行预测 # 首先获取之前构造好的kNN分类器.数据.规则 ...