微软同步框架入门之六--文件(夹)同步

     在前五篇文章当中,介绍了Sync For ADO.NET Service,从这篇文章开始,将开始介绍有关使用MSF进
文件(夹)同步的相关知识。因为文件同步的应用目前比较广泛,所以可能够要用3-4篇文章来进行介绍。今
天先介绍一下有关MSF文件同步的原理和使用MSF中现有的类来实现一个简单的DEMO(本DEMO支持文件和文
夹)同步。

     好的,下面开始今天的正文。
    

    Sync Services 可帮助应用程序在 NTFS、FAT 或 SMB 文件系统中同步文件、文件夹和子文件夹。要同
步的目录可为本地或远程目录,且不必同属一个文件系统。应用程序可以使用静态筛选器通过显式列出文件或使
用通配符(如 *.txt)来排除或包括这些文件;或者应用程序可以设置筛选器来排除整个子文件夹。应用程序还
可以注册以接收文件同步进度的通知。


    
    首先,我们需要了解一下MSF进行同步的原理。换句话说就是其进行文件同步的底层实现机制是什么?
   
    按MSF的SDK中所说明的(内置变更检测算法,用于检测针对同步作用域中的文件和文件夹所做的变更):      

MSF文件同步服务会对以下属性发生变更后进行所谓的"报告变更":
    1.最后一次修改文件的时间。
    2.如果启用哈希运算,则是为该文件计算的哈希值。(关于计算变更检测的哈希值: 如果应用程序在初始化提
供程序时指定了 CompareFileStreams 标志(对于托管代码)或 FILESYNC_INIT_FLAG_USE_HASHING 
标志(对于非托管代码),该提供程序将使用文件流的所有内容计算每个文件的哈希值。然后,该提供程序会比
较这些哈希值;这样做可以更准确地执行变更检测,但性能会稍有降低。在本DEMO中将不会使用该设置项)
    3.文件大小。
    4.文件或文件夹名称。此检查区分大小写。
    5.由提供程序处理的任意文件属性。

      如果发现文件与此前了解的文件具有相同的创建时间、大小和哈希值(如果使用了哈希运算),但是文
件的名称或路径不同,则报告文件移动或重命名。如果发现多个文件符合这些条件,Sync Services 将认为
原始文件已删除并且创建了新文件。
      Sync Services 将文件夹移动或重命名视作已删除旧文件夹并且创建了新文件夹。报告该文件夹中的文
件已移动。因此在这种情况下,通常无需重新发送文件数据。

 

      上面介绍是的文件同步时所依据的“证明”(即凭什么来解释当前文件被修改,以及修改的地方在哪里)
下面是其工作时的同步流程。
   
      MSF 通过使用三个基本组件来同步数据存储区或“副本”:一个同步会话和两个同步提供程序。为了同
步数据,应用程序创建一个同步会话,并向它传递一个源提供程序和一个目标提供程序。此会话使用源提供
序获取源副本中已发生的新变更,并使用目标提供程序将这些变更应用于目标副本。如下图:

 

  

 

     注:除上图之外,MSF还支持下列参与者类型:代理参与者,部分参与者,简单参与者。详情参见链接:) 


     在同步过程中,上面的三个基本组件要同步的副本都必须向“同步社区”提供一组描述其本身及其知识
的元数据。即每个副本所需的元数据为:副本 ID、当前滴答计数、副本键映射、当前知识、遗忘的知识、
冲突日志和逻辑删除日志(将会在下一篇中介绍如何创建和维护这些元数据)。副本还必须为要同步的每个
项维护元数据。每个项所需的元数据为:全局 ID、当前版本和创建版本。通常,同步提供程序管理同步所
需的元数据。然而,根据副本的实现,由单独的组件来处理元数据管理的某些部分可能更有用,例如,一项
在预定时间(非不是在同步过程中)清除逻辑删除的服务。

     上面的原理看起来很复杂,但使用MSF进行文件同步却很简单,可以说只要初始化相应的三个组件(一
同步会话和两个同步提供程序)然后进行相应的属性绑定并执行同步即可。下面将会简要介绍一下这三个
件类型。

    SyncOrchestrator:启动和控制同步会话。包含两个将参与同步的 SyncProvider 对象。它能够启动
控制同步会话,并向应用程序调度进度事件。该类的角色就是我们之前看ado.net sync service中的:
    SyncSnapDataSyncAgent
   
   
    FileSyncProvider:同步提供程序。若要同步目录中的所有文件和子文件夹,请将副本 ID 和根目录传
递到 FileSyncProvider(Guid,String),并将该提供程序传递到 SyncOrchestrator 对象以处理同步会话。

    当前上面有三个组件的一般初始化过程是这样子的:
   
    首先定义两个同步提供程序:“源”和“目标”提供程序。    

    FileSyncProvider sourceProvider = null;
    FileSyncProvider destinationProvider 
= null;

 

    然后初始化相应的对象实现如下:     

     sourceProvider = new FileSyncProvider(
                    sourceReplicaId, sourceReplicaRootPath, filter, options);

          
     destinationProvider 
= new FileSyncProvider(
                    destinationReplicaId, destinationReplicaRootPath, filter, options);

 

    上面语句中的sourceReplicaId,destinationReplicaId即是相应的副本ID。而sourceReplicaRootPath
和destinationReplicaRootPath则是同步的源和目标文件夹的路径。

    第三个参数filter是一个FileSyncScopeFilter实例,该类工作就是定义可用于包括或排除静态同步作用
域中的文件或文件夹的筛选器。其中静态筛选器应用于变更检测,对同步作用域中的所有项都适用。对于要
包括在同步中的项,它必须传递所有静态筛选器。例如,如果某个文件同时被显式排除和显式包括,则该文
件将从作用域中排除。
    在实际环境中应该对同步社区中的所有提供程序都使用同一作用域筛选器。如果未执行此操作,则可能
发生意外行为。传递给 FileSyncProvider 的筛选器用于在传入时根据作用域筛选器初始化提供程序对象。
该筛选器的后续变更将不影响提供程序实例所使用的作用域筛选器。若要变更所使用的作用域筛选器,必须
创建新的文件同步提供程序对象。
 
     在本例中,该对象的实例化过程如下:
     

 

 string idFileName = "filesync.id";

 FileSyncScopeFilter filter 
= new FileSyncScopeFilter();
 filter.FileNameExcludes.Add(idFileName); 

 
    FileSyncProvider的第四个参数是个枚举类型,即:FileSyncOptions。    

    FileSyncOptions:提供配置文件同步提供程序的行为的选项。可将包含这些选项的组合的值传递到
                  FileSyncProvider,以配置文件同步提供程序将对同步过程不同部分的处理方式。
                  这些选项包括:
     
    CompareFileStreams: 如果设置了此值,则提供程序将基于整个文件流的内容计算每个文件的哈希值,
                  并在变更检测期间使用此值对这些文件进行比较。此选项会占用大量资源并将使同步减
                  速,但可提供更强大的变更检测。如果未设置此值,则比较修改次数、文件大小、文件
                  名称和文件属性的算法将用于确定文件是否已变更。 
    ExplicitDetectChanges: 如果设置了此值,则仅当调用 DetectChanges 时提供程序才执行变更检测。
                  如果不设置此值,则在首次调用提供程序的 GetChangeBatch 或 ProcessChangeBatch 
                  方法时隐式执行变更检测。 
    None: 如果设置了此值,则提供程序将使用其默认配置选项。设置任何其他标志将覆盖此设置。这是
            默认设置。 
    RecycleConflictLoserFiles: 如果设置了此值,则提供程序将把冲突解决落选方文件移至回收站。如
                  果未设置此值,则提供程序将把这些文件移至指定位置。或者,如果未指定位置,则将
                  永久删除这些文件。 
    RecycleDeletedFiles:如果设置了此值,则提供程序将把变更应用期间删除的文件移至回收站。如果未
                  设置此值,则将永久删除这些文件。 
    RecyclePreviousFileOnUpdates:   如果设置了此值,则提供程序将把变更应用期间覆盖的文件移至回
                  收站。如果未设置此值,则将就地覆盖文件并且会丢失旧文件中的所有数据。 

   
   
    本DEMO中的该选项设置如下:   

FileSyncOptions options = FileSyncOptions.ExplicitDetectChanges | FileSyncOptions.RecycleDeletedFiles
          
| FileSyncOptions.RecyclePreviousFileOnUpdates | FileSyncOptions.RecycleConflictLoserFiles;

 


    在定义并实例化相应的“同步提供程序”之后,接下来就是要执行变更检测,也就是执行相应的同步提
供程序的DetectChanges()方法,该方法会对本地同步元数据进行检测更新,如下:

     sourceProvider.DetectChanges();
    
     destinationProvider.DetectChanges();

 

     接着就是“启动和控制同步会话”的过程,完成这个工作的是上面所说的“SyncOrchestrator”。下面就
是本DEMO中的相关代码:      

   //启动和控制同步会话。
    SyncOrchestrator agent = new SyncOrchestrator();
    agent.LocalProvider 
= sourceProvider;
    agent.RemoteProvider 
= destinationProvider;
    agent.Direction 
= SyncDirectionOrder.Upload; 
    
//注:SyncDirectionOrder指示同步的方向。 对于双向同步,还包括执行同步的顺序。
    
//        Download 仅下载。 
    
//        DownloadAndUpload 先下载,再上载。 
    
//        Upload 仅上载。 
    
//        UploadAndDownload 先上载,再下载。 
    
//备注:方向与同步提供程序的相对位置结合使用,可确定同步期间的变更流。 上载意味着变更源于本地提
    
//供程序,并应用到远程提供程序。 下载意味着变更源于远程提供程序,并应用到本地提供程序。
    agent.Synchronize();    //此处开始执行文件(夹)同步。

    
    大家看到了,整个定义和初始化过程很清楚。也与之前在ado.net sync service中的代表结构相类似。
所以接受起来并不难。

    当然到这里主要的代码就开发完了。

    下面我们就开始测试一下这个DEMO,测试过程如下:
    1.我们在“C:\”下新建两个目录“folder1”和“folder2”,然后在“folder1”文件夹下新建一个TXT
      文件,并在里面随意输入一些内容。

    2.启动DEMO,其界面如下:

   
   
    这样就将folder1下面的txt文件同步到folder2中了。当然本DEMO也支持对文件夹的同步,大家可以自行测
试一下便知。当然也可以尝试修改folder1下的TXT文件的内容并保存,然后再进行同步,这时folder2中的文件
内容也被同步更新了。

    最后是 Sync Framework 词汇表,了解这些术语,有助于学习MSF和它的SDK并研究相关的示例代码。 

    批处理 (batching) :分若干组来发送变更而非一次完成所有数据的传输的过程。

    变更单位 (change unit) :存储区中跟踪变更的最小单位。变更单位包含在项中,如联系人项中的姓名和
        地址字段。传播变更时,只发送已发生变更的变更单位。检测冲突时,只将对同一变更单位所做的变
        更视为冲突。

    客户端 (client) :
        要集成到 Sync Framework 体系结构的服务、应用程序或设备。

    时钟向量 (clock vector):
        表示对副本的更新的副本键
/滴答计数对。在 0 到该滴答计数之间发生的任何变更将包含在向量中。

    冲突解决方法 (conflict resolution method):
        用于确定在有冲突时将哪个变更写入存储区的方法。一般冲突解决方法如下:后写入者胜出、源胜出、
    目标胜出、自定义解决方法或延迟解决方法。对于自定义解决方法,解决应用程序读取冲突日志中的冲突
    并选择一种解决方法。对于延迟解决方法,记录冲突时同时记录发生冲突的变更数据以及变更的生成知识。

   一致性单位 (consistency unit): 
       一致性的最小单位。由于一起发送具有相同一致性单位的所有变更,在仅应用一致性单位的一部分时
   将不中断同步。

   可变标识符 (flexible identifier) :
       分配给各种同步实体(如副本)的标识符。标识符的长度可以是固定的,也可以是可变的。

   全局标识符 (
global identifier) :
       分配给数据项的唯一标识符。该标识符在所有客户端上必须是唯一的。全局标识符是可变标识符,因此
   它可以使用任何格式。一般格式为 GUID 和 
8 字节的前缀。

   项 (item) :
       正在同步的数据或元数据的单位。数据的一般项可能是文件或记录,元数据的一般项则可能为知识项。

   生成知识 (made
-with knowledge) :     
       要在冲突检测中使用的源副本的当前知识。生成知识回答以下问题:在执行这些变更时知道什么?

   已知知识 (learned knowledge) :
       有关特定一组变更的源副本的当前知识以及记录的该副本的冲突信息。已知知识回答以下问题:在应用
   此批变更时将获得哪些信息?

   知识 (knowledge) :
       由每个参与者维护的、描述自己所知道的所有变更的元数据。采用最简单的形式(即水印)时,知识项
   为由若干对副本键和副本滴答计数组成的时钟向量。

   参与者 (participant) :一个提供程序及其相关副本。

   范围 (range) :
       应用同一时钟向量的一组连续的项标识符。范围用起点、终点以及应用于起点和终点之间的所有 ID 的
   时钟向量表示。

   副本 (replica) :要同步的信息的特定存储库。

   副本 ID (replica ID) :用于唯一标识副本的值。

   副本键 (replica key) :在副本键映射中映射为副本 ID 的 
4 字节的值。

   作用域 (scope) :正在同步的数据的集合。

   同步应用程序 (synchronization application) :
       诸如个人信息管理器或乐曲数据库之类的软件组件,用于承载同步会话并调用同步提供程序以同步不同
   的数据存储。

   同步社区 (synchronization community) :保持数据相互同步的一组副本。

   同步提供程序 (synchronization provider) :
       表示同步的副本的软件组件。作为源时,它枚举自己副本的变更。作为目标时,它将变更应用到自己的
   副本。数据格式不匹配时,它执行所需的架构转换。

   同步会话 (synchronization session) :
       一种单向同步,在其中源提供程序枚举自己的变更并将这些变更发送到目标提供程序,目标提供程序将
   变更应用到自己的存储区。

   滴答计数 (tick count) :副本特定的单调递增的数字,它与副本键一起构成版本。

   逻辑删除 (tombstone) :用于表示已删除的项的标记。逻辑删除用于跟踪已删除的项并防止重新将它们引
       入同步社区。

   版本 (version) :标识对项的修订的元数据。它由项的副本键和副本滴答计数组成。

   

    今天的内容就先到这里了,在下一篇文章中,将会进一步介绍如何定义自己的KnowledgeSyncProvider。来
实现更加灵活的对每个副本的元数据:当前滴答计数、副本键映射、当前知识、遗忘的知识、冲突日志和逻辑删
除日志等信息进行定义和维护。

   

     原文链接:http://www.cnblogs.com/daizhj/archive/2008/11/24/1339688.html

     作者: daizhj, 代震军

     Tags: 微软同步框架,file sync,文件同步

     网址: http://daizhj.cnblogs.com/

     DEMO下载,请点击这里

posted @ 2008-12-01 09:14  代震军  阅读(5531)  评论(20编辑  收藏  举报