使用C#如何监控选定文件夹中文件的变动情况?
目录
1、前言
2、效果
3、具体实现
页面设计
全部代码
FileSystemWatcher的介绍
FileSystemWatcher的构造函数
FileSystemWatcher的属性
FileSystemWatcher的事件
4、总结
前言
有时候我们会有监控电脑上某一个文件夹中文件变动情况的需求,在本文中,我也会以一个具体的例子,说明在C#中如何使用FileSystemWatcher类来实现上述需求。
效果


具体实现
如果你对C#如何监控选定文件夹中文件的变动情况感兴趣,可以继续往下阅读。
界面设计
为了更好的演示效果,我这里winform的界面设计如下:

很简单,只有一个button与一个richtextbox,button用来指定被监控的文件,richtextbox用来输出一些信息。
全部代码
namespace FileSystemWatcherDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 创建一个 FolderBrowserDialog 实例
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
// 设置对话框的标题
folderBrowserDialog.Description = "选择文件夹";
// 如果用户点击了“确定”按钮
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
richTextBox1.Text = "";
// 获取用户选择的文件夹路径
string selectedFolder = folderBrowserDialog.SelectedPath;
// 提示被监控文件夹路径
richTextBox1.Text += $"被监控的文件夹为:{selectedFolder}\r\n";
var watcher = new FileSystemWatcher($"{selectedFolder}");
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Changed += OnChanged;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
watcher.Renamed += OnRenamed;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
}
else
{
MessageBox.Show("您本次没有选择文件夹!!!");
}
}
private void AppendMessageToRichTextBox(string message)
{
// 在RichTextBox中添加提示信息
richTextBox1.Invoke(new Action(() =>
{
richTextBox1.AppendText(message + Environment.NewLine);
}));
}
private void OnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Changed)
{
return;
}
AppendMessageToRichTextBox($"Changed: {e.FullPath}");
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
string value = $"Created: {e.FullPath}";
AppendMessageToRichTextBox($"Created: {e.FullPath}");
}
private void OnDeleted(object sender, FileSystemEventArgs e)
{
AppendMessageToRichTextBox($"Deleted: {e.FullPath}");
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
AppendMessageToRichTextBox($"Renamed:");
AppendMessageToRichTextBox($" Old: {e.OldFullPath}");
AppendMessageToRichTextBox($" New: {e.FullPath} ");
}
}
}
FileSystemWatcher的介绍
看过以上代码,会发现核心就是FileSystemWatcher的使用。接下来我将介绍一下C#中的FileSystemWatcher类。
FileSystemWatcher是C#中的一个类,该类可以侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。
FileSystemWatcher的构造函数
该类有三种构造函数,如下所示:
| 形式 | 含义 |
|---|---|
| FileSystemWatcher() | 初始化 FileSystemWatcher 类的新实例。 |
| FileSystemWatcher(String) | 初始化 FileSystemWatcher 类的新实例,给定要监视的目录。 |
| FileSystemWatcher(String, String) | 初始化 FileSystemWatcher类的新实例,给定要监视的目录和文件类型。 |
var watcher = new FileSystemWatcher($"{selectedFolder}");
本文中我选择的就是第二种构造函数,指定要监视的目录。
FileSystemWatcher的属性
现在介绍一下在本示例中用到的FileSystemWatcher的属性,如下所示:
| 名称 | 类型 | 含义 |
|---|---|---|
| EnableRaisingEvents | bool | 设置FileSystemWatcher是否有效 |
| Filter | string | 设置一个要监控的文件的格式 |
| Filters | Collection | 设置多个要监控的文件的格式 |
| IncludeSubdirectories | bool | 获取或设置一个值,该值指示是否应监视指定路径中的子目录 |
| NotifyFilter | NotifyFilters | 获取或设置要监视的更改的类型 |
| Path | string | 获取或设置要监视的目录的路径 |
现在来解释下所用到的代码的含义:
watcher.Filter = "*.txt";
表示要监控的文件为.txt格式。
watcher.IncludeSubdirectories = true;
表示指定路径中的子目录也要监视。
watcher.EnableRaisingEvents = true;
表示该对象可以触发事件,也就是还有效。
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
设置要监视的更改的类型。NotifyFilter属性的类型为NotifyFilters枚举类型。
NotifyFilters枚举类型:
[System.Flags]
public enum NotifyFilters
指定要在文件或文件夹中监视的更改。
此枚举支持其成员值的按位组合。
该枚举类型包含的值与含义如下所示:
| 名称 | 含义 |
|---|---|
| Attributes | 文件或文件夹的属性 |
| CreationTime | 文件或文件夹的创建时间 |
| DirectoryName | 目录名 |
| FileName | 文件的名称 |
| LastAccess | 文件或文件夹上一次打开的日期 |
| LastWrite | 上一次向文件或文件夹写入内容的日期 |
| Security | 文件或文件夹的安全设置 |
| Size | 文件或文件夹的大小 |
在这里使用了该枚举类型的按位组合表示这几种更改的类型要受到监视。
FileSystemWatcher的事件
FileSystemWatcher中的事件如下:
| 名称 | 含义 |
|---|---|
| Changed | 当更改指定 Path 中的文件和目录时发生 |
| Created | 当在指定Path 中创建文件和目录时发生 |
| Deleted | 删除指定Path中的文件或目录时发生 |
| Renamed | 重命名指定 Path中的文件或目录时发生 |
| Error | 当 FileSystemWatcher 的实例无法继续监视更改或内部缓冲区溢出时发生 |
watcher.Changed += OnChanged;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
watcher.Renamed += OnRenamed;
在这里我使用到了Changed、Created、Deleted和Renamed事件。
我将以Changed 事件为例,详细解释一下:
watcher.Changed += OnChanged;
这行代码的含义。
我们查看FileSystemWatcher的源代码,Changed事件的代码如下所示:
/// <devdoc>
/// Occurs when a file or directory in the specified <see cref='System.IO.FileSystemWatcher.Path'/> is changed.
/// </devdoc>
public event FileSystemEventHandler? Changed
{
add
{
_onChangedHandler += value;
}
remove
{
_onChangedHandler -= value;
}
}
可知将值赋给了_onChangedHandler,我们再来查看_onChangedHandler的定义:
// Event handlers
private FileSystemEventHandler? _onChangedHandler;
类型为FileSystemEventHandler?与Changed事件一致,再来看看FileSystemEventHandler?的定义:
public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);
发现是一个参数类型分别为object、FileSystemEventArgs返回值类型为空的委托类型。
object我们知道,那么FileSystemEventArgs又是什么呢?
查看它的源码,截取一部分,如下所示:
public class FileSystemEventArgs : EventArgs
{
private readonly WatcherChangeTypes _changeType;
private readonly string? _name;
private readonly string _fullPath;
/// <devdoc>
/// Gets one of the <see cref='System.IO.WatcherChangeTypes'/> values.
/// </devdoc>
public WatcherChangeTypes ChangeType
{
get
{
return _changeType;
}
}
/// <devdoc>
/// Gets the fully qualified path of the affected file or directory.
/// </devdoc>
public string FullPath
{
get
{
return _fullPath;
}
}
/// <devdoc>
/// Gets the name of the affected file or directory.
/// </devdoc>
public string? Name
{
get
{
return _name;
}
}
}
发现FileSystemEventArgs继承自EventArgs,而EventArgs表示包含事件数据的类的基类,因此可以明白FileSystemEventArgs表示为目录事件:Changed, Created, Deleted提供数据的类。
FileSystemEventArgs提供三个数据分别为ChangeType、FullPath、Name。
那ChangeType是什么呢?
查看ChangeType的定义:
//
// 摘要:
// Changes that might occur to a file or directory.
[Flags]
public enum WatcherChangeTypes
{
//
// 摘要:
// The creation of a file or folder.
Created = 1,
//
// 摘要:
// The deletion of a file or folder.
Deleted = 2,
//
// 摘要:
// The change of a file or folder. The types of changes include: changes to size,
// attributes, security settings, last write, and last access time.
Changed = 4,
//
// 摘要:
// The renaming of a file or folder.
Renamed = 8,
//
// 摘要:
// The creation, deletion, change, or renaming of a file or folder.
All = 15
}
是一个枚举类型,表示更改的类型。
现在回过头来看:
watcher.Changed += OnChanged;
OnChanged方法如下:
private void OnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Changed)
{
return;
}
AppendMessageToRichTextBox($"Changed: {e.FullPath}");
}
为什么可以将OnChanged方法订阅到watcher.Changed事件上呢?
因为OnChanged方法与watcher.Changed事件中的委托类型FileSystemEventHandler的返回类型和签名是相同的。
OnChanged方法的返回类型与签名如下:
private void OnChanged(object sender, FileSystemEventArgs e)
FileSystemEventHandler委托类型的定义如下:
public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);
现在已经理解了订阅事件,那么什么时候触发事件呢?
查看FileSystemWatcher的部分源码:
/// <devdoc>
/// Raises the <see cref='System.IO.FileSystemWatcher.Changed'/> event.
/// </devdoc>
protected void OnChanged(FileSystemEventArgs e)
{
InvokeOn(e, _onChangedHandler);
}
private void InvokeOn(FileSystemEventArgs e, FileSystemEventHandler? handler)
{
if (handler != null)
{
ISynchronizeInvoke? syncObj = SynchronizingObject;
if (syncObj != null && syncObj.InvokeRequired)
syncObj.BeginInvoke(handler, new object[] { this, e });
else
handler(this, e);
}
}
当发生相应的改变时,就会调用FileSystemWatcher类的OnChanged方法,从而触发事件。
总结
本文通过一个实例,介绍了如何通过C#中的FileSystemWatcher类实现监控选定的文件夹,希望对你有所帮助。
使用C#如何监控选定文件夹中文件的变动情况?的更多相关文章
- C# 将文件夹中文件复制到另一个文件夹
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- python批量处理文件夹中文件的问题
用os模块读取文件夹中文件 原来的代码: import osfrom scipy.misc import imread filenames=os.listdir(r'./unprocess')for ...
- php获取指定文件夹中文件名称
/** * php获取指定文件夹中文件名称 * @author jackie <2018.10.10> */ public static function getFileName($fil ...
- Python按顺序读取文件夹中文件
参考资料: https://blog.csdn.net/qq_22227123/article/details/79903116 https://blog.csdn.net/merdy_xi/arti ...
- C#实现对指定文件夹中文件按修改时间排序
string path = "~/Document/Introduction/团队管理制度/"; DirectoryInfo dirinfo = new Di ...
- 【linux】复制文件夹中文件,排除部分文件
如下 cp `ls|grep -v -E '*json|out'|xargs` /home/data/ 用grep -v 表示排除, -E 表示正则 ls|grep -v -E '*json|out ...
- Java访问文件夹中文件的递归遍历代码Demo
上代码: import java.io.File; /* * 需求:对指定目录进行所有内容的列出(包含子目录中的内容) * 也可以理解为 深度遍历. */ public class FindAllFi ...
- Python之获取文件夹中文件列表以及glob与fnmatch模块的使用
获取文件夹中的文件列表 print(os.listdir("../secondPackage")) # ['__init__.py', 'secondCookBook.py', ' ...
- 使用java读取文件夹中文件的行数
使用java统计某文件夹下所有文件的行数 经理突然交代一个任务:要求统计某个文件夹下所有文件的行数.在网上查了一个多小时没有解决.后来心里不爽就决定自己写一个java类用来统计文件的行数,于是花了两个 ...
- 使用.NET统计文件夹中文件总数
软件下载: http://hovertree.com/h/bjaf/hwqtjwjs.htm 截图: 使用方法:点击按钮,选择文件夹,就可以显示文件夹中包含的文件总数. 这个项目包含在HoverTre ...
随机推荐
- 如何理解SpringBoot的Starter
Starter是SpringBoot的四大核心功能特性之一,除此之外,SpringBoot还有自动装配,Actuator监控等特性 SpringBoot里面的这些特性,都是为了让开发者在开发基于Spr ...
- Solution -「BalticOI 2004」Sequence
Description Link. Given is a sequencen \(A\) of \(n\) intergers. Construct a stricly increasing sequ ...
- Github 组合搜索开源项目 (超详细)
例如搜索 Spring Boot 相关项目 spring boot (最简单最常用) in:name spring boot (匹配项目名字) in:name spring boot stars: ...
- 看完这篇HTTP,跟面试官扯皮就没问题了(转)
认识 HTTP 首先你听的最多的应该就是 HTTP 是一种 超文本传输协议(Hypertext Transfer Protocol),这你一定能说出来,但是这样还不够,假如你是大厂面试官,这不可能是他 ...
- replace批量替换、表删除数据查询用法
一. select * from baec_file where bacti='1'order by baec01; select baec02,REPLACE(baec02,'白班','A班') f ...
- 使用yum管理RPM软件包
yum概念 对比rpm命令,rpm命令需要手动寻找安装该软件包所需要的一系列依赖关系.当软件包需要卸载时,容易由于卸载掉了某个依赖关系而导致其他的软件包不能用. yum(Yellow dog upda ...
- mac应用已损坏无法打开
sudo xattr -r -d com.apple.quarantine /User/name/yourapp # '/User/name/yourapp' 替换成你自己要安装的 mac 应用地址 ...
- linux内核离线升级步骤详解【亲测可用】
由于种种原因,linux的内核版本需要升级,但由于生产原因往往不能在线升级,在此记录笔者本人昨晚的的离线升级步骤,亲测可用. 我们知道,红帽和CentOS同源同宗,内核升级步骤也是一样的. 目录 ■ ...
- 轻量通讯协议 --- MQTT
介绍 一.MQTT简介 MQTT(Message Queuing Telemetry Transport) 是一种轻量级的消息传输协议,通常用于在物联网(IoT)和传感器网络中进行通信.它设计用于在低 ...
- 一个Node.js的小爬虫
爬虫其实就是对网页内特定id.class.标签内容的提取,多是循环出来的,对我们爬取非常便利. 1.安装node node官网下载安装包安装,后在命令行工具中输入node -v查看node安装的版本. ...