0 引言
要使两个文件夹同步,需要一个监控工具时刻监控这两个文件夹,比较两个文件夹的不同之处。当源或目标文件夹发生变化,比如添加或删除了某个文件后,同步工具可以实时同步,若手工实现文件夹同步,工作量较大且容易出错。
1 文件夹同步
为了让文件夹实时同步,需要一个工具不停地监控两个文件夹的异同,该工具实现了一个专门的Windows服务来实现文件夹的同步功能。因为实时同步功能要耗费系统资源,所以可以制定同步服务间隔时间,该工具要能让用户配置这个Windows服务,如添加同步项、设置同步时间等 [1]。
2 文件同步核心功能实现
由于文件同步服务可以放在Windows服务中,也可以运行在一个Windows Forms类型的控制台应用程序上[2],所以将同步核心功能实现为一个文件操作类库项目 SynchroLib,以便多次重用,该类库项目中的主要类包括:①SyncItem类:表示一个文件同步项;②SyncItemCollection 类:派生自泛型的List集合,表示同步项集合;③SyncSettings类:保存或加载同步项的设置;④FileInfoEx类:表示一个文件信息类;⑤FileInfoList类:派生自泛型的List集合,表示文件集合。
2.1 文件夹同步项实现
SynchroLib项目中的同步项允许用户指定文件同步的来源或者目标文件,以及是否进行备份等相关的设置。SyncItem类实现了单个同步项的同步功能,SyncItemCollection提供了管理多个同步项的功能。当用户在设置窗口中添加了同步项后,这些同步项将保存为XML元素,SyncItem将从XML元素中解析出同步项的相关属性,然后开始同步操作[3]。
2.2 文件夹同步项SyncItem类
集合中的每个项都是一个SyncItem对象,实现各自的同步功能。SyncItem类的属性定义了同步项所需要的各种属性,包含源和目标路径、是否备份、是否删除等。其中XElement属性比较特别,该属性会将同步项中的属性值作为一个XML元素返回,当设置一个XElement类型的对象时,会从 XML元素中获取属性值,这是因为同步项最终要保存到XML中去,作为一个XML元素存在[4]。
2.3 文件备份操作实现
在同步选项中,如果要求对目标文件进行备份,备份操作不只是简单地将目标文件拷贝到备份文件夹下。备份操作提供版本保留机制,将原来的老版本文件进行更名保存,以便用户从老版本中恢复[5]。
3 文件同步Windows服务技术实现
Windows服务程序是由操作系统托管的,在后台长期运行的程序可以随操作系统的启动而启动。因为长驻操作系统,所以Windows服务程序通常较少与用户交互。需要长时间运行的程序,可以使用Windows操作系统的服务控制台来查看当前操作系统的Windows服务列表 [6]。
3.1 创建Windows服务项目
打开Visual Studio 2010,选择主菜单中的“文件”、“新建”、“项目”命令,在弹出的窗口中选择Windows服务项目,命名为SynchroService。单击“确定”按钮后,Visual Studio 2010产生了一个服务组件Service1.cs和Program.cs文件。有了服务组件后,还需要添加专用的安装组件。在解决方案资源管理器中双击Service1.cs文件,Visual Studio将切换到设计视图,右击设计视图面板,在弹出的菜单中选择“添加安装程序”选项,Visual Studio 2010将产生一个服务安装文件,在该文件的设计视图上添加了两个组件ServiceInstaller和ProcessInstaller。删除这两个组件,在后台代码中手工实现这两个组件。
实现Windows服务只需要在Service1.cs中重载几个方法即可,也就是启动OnStart()、停止OnStop()、暂停 OnPause()等方法。因为Service1从ServiceBase基类派生,而该类实现了Windows服务需要的基本功能,所以开发人员只需要重载几个方法就可以完成一个服务的创建。为使同步操作能够暂停、停止等,在服务类的字段声明中定义了几个属性来实现调用同步过程 [7]。
3.2 使用程序代码控制Windows服务
要使用程序代码控制Windows服务,需要使用ServiceController类,该类位于System.ServiceProcess命名空间中,可以很方便地实现对服务的控制,并且可以实现对远程计算机服务的访问。例如,要获取计算机上所有的服务列表,可以使用 ServiceController的GetServices()方法,该方法返回ServiceController数组,每一个 ServiceController表示一个服务。
通过循环计算机上已安装的服务,判断服务名称是否与指定的服务名称一致,以此来判断服务是否安装,其实现代码如下:
public static bool IsServiceInstalled()
{
bool installed=false;
ServiceController[] services= ServiceController.GetServices();
foreach(ServiceController service in services)
{
if(service.ServiceName==m_serviceName)
{
SynchroService=new ServiceController(m_serviceName);
installed=true;
break;
}
}
return installed;
}
在代码中,通过使用ServiceController的GetServices()方法,获取当前计算机上已安装的服务列表,然后循环服务列表,通过 ServiceController的ServiceName来获取服务名称,通过对名称的比较来查找特定的服务在服务列表中是否已经存在,如果存在,则表示服务已经成功安装。
ServiceController类具有一个为ServiceControllerStatus枚举类型的属性,该属性用来返回当前服务的状态。该枚举定义如下:
public enum ServiceControllerStatus
{
Stopped=1, //服务已停止
StartPending=2, //服务正在开始
StopPending=3, //服务正在停止
Running=4, //服务正在运行
ContinuePending=5, //服务正在继续
PausePending=6, //服务正在暂停
Paused=7, //服务暂停
}
通过判断ServiceController的Status属性可以获知服务当期的运行状态。ServiceController提供了Start()、Stop()和Pause()等方法来控制服务的启动、停止和暂停。通过StartStopService()方法判断Status属性的值,来启动或停止服务,代码如下:
public static void StartStopService(bool restart)
{
try
{
if(IsServiceInstalled())
{
TimeSpan timeout=TimeSpan.FromMilliseconds(SERVICE_TIMEOUT);
if(SynchroService.Status==ServiceControllerStatus.Running)
{
SynchroService.Stop();
SynchroService.WaitForStatus(ServiceControllerStatus.Stopped,timeout);
}
if(restart)
{
SynchroService.Start();
SynchroService.WaitForStatus(ServiceControllerStatus.Stopped,timeout);
}
StartStopServiceEvent(SynchroService,new StartStopServiceEventArgs());
}
else
{
throw new Exception(string.Format("不能{0}服务-SynchroService对象为空",(restart) "启动/重新启动":"停止"));
}
}
catch (Exception ex)
{
throw new Exception(string.Format("服务不能被{0}:\\n\\n{1}",(restart) "启动/重新启动":"停止",ex.Message));
}
}
在代码中,首先调用IsServiceInstalled判断服务是否存在于服务列表中,timeout用于指定服务在启动或停止时[dylW.net专业提供教育论文写作的服务,欢迎光临www.dylW.NeT] 的超时值;然后判断服务状态,如果为运行状态,则调用Stop()方法关闭服务。在调用Stop()方法后,需要使用WaitForStatus等待服务状态的变化。如果服务需要启动,则调用Start()方法启动服务,同样需要使用WaitForStatus等待服务状态的改变。当服务成功切换状态后,触发StartStopServiceEvent事件更新用户界面 [8]。
通过Windows服务,使一个或多个文件夹自动复制备份,最终实现了同步功能。
参考文献:
\[1\] 孙静,王保保.远程文件同步系统设计与实现[J].电子科技,2010(12):103-106.
[2] 李强,朱立谷,曾赛峰.弱连接网络环境中的多主机文件同步[J].小型微型计算机系统,2012(10):83-89.
[3] 刘珺,叶勇,石竹.文件同步系统的研究和实现[J].信息安全与通信保密,2014(2):79-82.
[4] 欧志先.利用FileSystemWatcher进行异地文件同步操作[J].科学咨询,2008(5):63-66.
[5] 刘晓峰,刘智斌,禹继国.基于Web的多文件同步无组件上传[J].电子技术,2013(4):75-78.
[6] 胡勃.SugarSync:多平台文件同步[J].互联网天地,2010(7):81-85.
[7] 张敏.浅谈电子文件与纸质文件同步存档的重要性[J].科技创新导报,2013(11):48-51.