博客园里面有很多同步工具和软件,关于FileSystemWatcher类解释的也很多,但收集了很多文章后,感觉没好的方法,自己没事写了一个定时文件同步,借鉴了很多博客园朋友的东西:

上主菜:

  配置文件:

<appSettings>
<!--原地址(多地址;隔开)-->
<add key="OldAddress" value="F:\bakup\1;F:\bakup\3"/>
<!--目标地址-->
<add key="NewAddress" value="F:\bakup\2"/>
<!--自动同步时间一般晚上23点开始-->
<add key="syncTime" value="23"/>
<!--要过滤的文件夹(多文件名;隔开)-->
<add key="FiltrationFile" value="Error"/>
<!--要过滤的文件后缀(多后缀;隔开)-->
<add key="FiltrationSuffix" value="log"/>
</appSettings>

  FileSystemWatcher类的Changed事件在每次文件添加和修改的时候,都会触发多次,不晓得微软为什么会有这样的考虑,我看博客园很多人给的解决方案是记录文件写入时间,同一文件写入文件不得小于500ns;

  

lock (dict)
{
//过滤文件夹
if (FiltrationFile(e.FullPath)) return;
//过滤文件后缀
if (FiltrationSuffix(e.Name)) return;
if (dict.ContainsKey(e.FullPath))
{
if ((new FileInfo(e.FullPath).LastWriteTime - dict[e.FullPath]).TotalMilliseconds <= ) //同一文件写入时间不得小于500ns
return;
else
dict.Remove(e.FullPath);
}
if (e.ChangeType == WatcherChangeTypes.Changed)
{
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
return;
}
//判断文件是否存在.
if (System.IO.File.Exists(e.FullPath) == true)
{
dict.Add(e.FullPath, new FileInfo(e.FullPath).LastWriteTime);
Task task = new Task(() =>
{
FileSave(e.Name, e.FullPath);
});
task.Start();
}
System.Threading.Thread.Sleep();
}
}

  在同步文件的时候,还有一个问题就是用户文件正在上传,这个触发Change事件都会报错,这个时候需要验证文件是否完整:

  /// <summary>
/// 判断文件是否完整
/// </summary>
/// <param name="path"></param>
private void Waiting(string path)
{
lock (this)
{
while (true)
{
try
{
FileStream stream = File.OpenRead(path);
stream.Close();
stream.Dispose();
return;
}
catch
{ System.Threading.Thread.Sleep();
}
}
}
}

  在一些项目中,一些日志文件或则一些固定的文件夹是不需要同步的,这都需要验证文件路径是否包含不同的文件夹和文件:

/// <summary>
/// 过滤文件夹
/// </summary>
private bool FiltrationFile(string fullPath)
{
try
{
string file = GetAppConfig("FiltrationFile");
if (string.IsNullOrEmpty(file)) return false;
file = file.ToLower();
if (File.Exists(fullPath) == true)
{
string[] items = file.Split(';');
List<string> list = fullPath.ToLower().Split('\\').ToList();
list.RemoveAt(list.Count - );
for (int i = ; i < items.Length; i++)
{
if (list.Count(a => a == items[i]) > )
{
return true;
}
}
}
}
catch (Exception exp)
{
WriteLog(exp.Message);
}
return false;
} /// <summary>
/// 过滤文件名后缀
/// </summary>
private bool FiltrationSuffix(string fileName)
{
try
{
string file = GetAppConfig("FiltrationSuffix");
if (string.IsNullOrEmpty(file)) return false;
file = file.ToLower();
string suffix = fileName.ToLower().Substring(fileName.LastIndexOf('.') + );
string[] items = file.Split(';');
for (int i = ; i < items.Length; i++)
{
if (items[i] == suffix)
{
return true;
}
}
}
catch (Exception exp)
{
WriteLog(exp.Message);
}
return false;
}

源码地址:http://files.cnblogs.com/xchit/SyncFile.rar(如果有更好的解决方法可以交流)

定时自动同步文件,支持多文件夹同步,支持过滤文件和文件夹,解决FileSystemWatcher多次文件触发事件(源码)的更多相关文章

  1. 支持语音识别、自然语言理解的微信小程序(“遥知之”智能小秘)完整源码分享

    记录自己搭建https的silk录音文件语音识别服务的调用过程,所有代码可在文中找链接打包下载 >>>>>>>>>>>>> ...

  2. Qt中QPushButton、QTabWidget等部件内容文字换行的解决方法(一定要写在源码里,写在翻译文件里不行,因为\n得不到转义)

    最近在做基于Qt的应用项目,其中有一个按钮文字超长,需要换一行显示.从网上找到的建议都是将要显示的内容做成图片,然后将图片设置为该按钮的背景.但是这样做有一个很大的局限性,当需要更改内容文字的时候,需 ...

  3. 【全网首创】修改 Ext.ux.UploadDialog.Dialog 源码支持多选添加文件,批量上传文件

    公司老框架的一个页面需要用到文件上传,本以为修改一个配置参数即可解决,百度一番发现都在说这个第三方插件不支持文件多选功能,还有各种各样缺点,暂且不讨论这些吧.先完成领导安排下来的任务. 任务一:支持多 ...

  4. .38-浅析webpack源码之读取babel-loader并转换js文件

    经过非常非常长无聊的流程,只是将获取到的module信息做了一些缓存,然后生成了loaderContext对象. 这里上个图整理一下这节的流程: 这一节来看webpack是如何将babel-loade ...

  5. golang 源码文件

    Go源码文件分三个种类: 1)命令源码文件:如果一个源码文件被声明属于main代码包,且该文件代码中包含无参数声明和结果声明的main函数,则它就是命令源码文件.命令源码文件可以通过go run命令直 ...

  6. class文件的基本结构及proxy源码分析二

    前文地址:https://www.cnblogs.com/tera/p/13267630.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...

  7. C#开发的高性能EXCEL导入、导出工具DataPie(支持MSSQL、ORACLE、ACCESS,附源码下载地址)[转]

    转自:http://www.cnblogs.com/yfl8910/archive/2012/05/19/2509194.html 作为财务数据核算人员,面对大量的业务与财务数据,借助于传统的EXCE ...

  8. 修改sqlarchemy源码使其支持jdbc连接mysql

    注意:本文不会将所有完整源码贴出,只是将具体的思路以及部分源码贴出,需要感兴趣的读者自己实验然后实现吆. 缘起 公司最近的项目需要将之前的部分业务的数据库连接方式改为jdbc,但由于之前的项目都使用s ...

  9. 优化Recorder H5录音:可边录边转码上传服务器,支持微信提供Android IOS Hybrid App源码

    Recorder H5 GitHub开源库随着支持功能的增多,音频转码处理效率渐渐的跟不上需求了,近期抽时间对音频转码部分进行了升级优化,以支持更多实用的功能. 另外IOS的Hybrid App也完成 ...

随机推荐

  1. boostrap兼容ie及其案例

    多梦网络 wordpress主题 http://www.dmeng.net/

  2. 【转】armeabi和armeabi-v7a

    原文网址:http://blog.csdn.net/dxpqxb/article/details/7721156 在我们android APK的根目录有一个 libs文件夹,此文件夹下包含了armea ...

  3. 第一个MVC模式的程序

    数据库 是一个SQL sever数据库,结构很简单,创建名为firstMVC的数据库,只包含一个数据表(名称为Persons),其中共有三列,分别用于保存人员(persons)的ID.姓名以及创建日期 ...

  4. Timus 1746 Hyperrook

    题意:在一个n维坐标系中,坐标的范围是0到m - 1,如果两个点坐标只有一个维度的坐标不同则可以相互移动,给出p个点,问任意两个点之间路径为d的个数是多少,答案与p取模. 解法:只需要考虑两个点之间不 ...

  5. POJ 1039 Pipe

    题意:一根管子,中间有一些拐点,给出拐点的上坐标,下坐标为上坐标的纵坐标减1,管子不能透过光线也不能折射光线,问光线能射到最远的点的横坐标. 解法:光线射到最远处的时候一定最少经过两个拐点,枚举每两个 ...

  6. Kooboo CMS的安装步骤

    Kooboo CMS的安装步骤 来自Kooboo document 跳转到: 导航, 搜索 http://www.microsoft.com/web/gallery/install.aspx?appi ...

  7. oracle spfile和pfile文件

    pfile(Parameter File)从oracle8i开始使用,在oracle9i中也可以用.它以文本文件的形式存在,可以用vi等编辑器对 其中数据库参数进行修改.文件格式为initSID.or ...

  8. 对Map按key和value分别排序

    一.理论准备         Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等.         TreeMap:基于红 ...

  9. 2015长春 HDU 5534 Partial Tree

    题意:有n个结点,n-1条边,现在要把这n个结点连成一棵树,给定了f(i),表示度为i的结点的价值是f(i).现在问如何连能够使得Σf(i)的值最大. 思路:每个点至少一个度,所以可分配的度数为n-2 ...

  10. C#调用C++ DLL类方法(转)

    http://hi.baidu.com/game_dev/item/ba29ecf67bd5f6cf521c26fc