正确使用OneDrive API同步文件的方法

时间:2017-02-18 12:37:14

标签: c# uwp onedrive

我找不到任何文档,概述了使用OneDrive存储和保存应用程序文件在C#中跨设备同步的正确方法

我已阅读OneDrive Dev Center的文档,但我不理解http代码。 (仅限自学C#)。

我有点明白我使用delta方法从OneDrive获取更改的文件,然后在本地保存,但我无法确切知道如何,所以通过使用{{手动检查本地vs OneDrive来解决它1}}方法。 我认为当前的实现(下面仅供参考)与API中可能处理得更好相比,相当笨拙。

此外,似乎没有反向'delta'功能?也就是说,我在本地向应用程序写入文件,然后告诉OneDrive同步更改。这是因为我需要使用GetAsync<>方法实际上传它吗? (目前正在做的事情)

PutAsync<>

1 个答案:

答案 0 :(得分:3)

同步需要几个不同的步骤,OneDrive API中的一些将帮助您,其中一些您将不得不自己做。

更改检测
显然,第一阶段是检测是否有任何变化。 OneDrive API提供了两种机制来检测服务中的更改:

  1. 可以使用If-None-Match的标准请求检测单个文件的更改:

    await this.userDrive.Drive.Special.AppRoot.ItemWithPath(remotePath).Content.Request(new Option[] { new HeaderOption("If-None-Match", "etag") }).GetAsync();
    

    如果文件根本不存在,您将获得404 Not Found。 否则如果文件没有改变,你将获得304 Not Modified 否则,您将获得该文件的当前状态。

  2. 可以使用delta API检测层次结构的更改:

    await this.userDrive.Drive.Special.AppRoot.Delta(previousDeltaToken).Request().GetAsync();
    

    这将返回自上次调用delta以来更改的所有项目的当前状态。如果这是第一次调用,previousDeltaToken将为null,API将返回AppRoot中所有项目的当前状态。对于响应中的每个文件,您需要再次进行服务往返以获取内容。

  3. 在本地方面,您需要枚举所有感兴趣的文件并比较时间戳以确定是否有变化。

    显然,前面的步骤需要了解“上次看到”的状态,因此您的应用程序需要在某种形式的数据库/数据结构中跟踪这一情况。我建议跟踪以下内容:

    +------------------+---------------------------------------------------------------------------+
    |     Property     |                                   Why?                                    |
    +------------------+---------------------------------------------------------------------------+
    | Local Path       | You'll need this so that you can map a local file to its service identity |
    | Remote Path      | You'll need this if you plan to address the remote file by path              |
    | Remote Id        | You'll need this if you plan to address the remote file by unique id         |
    | Hash             | The hash representing the current state of the file                       |
    | Local Timestamp  | Needed to detect local changes                                            |
    | Remote Timestamp | Needed for conflict resolution                                            |
    | Remote ETag      | Needed to detect remote changes                                           |
    +------------------+---------------------------------------------------------------------------+
    

    此外,如果使用delta方法,您需要存储token响应中的delta值。这与项目无关,因此需要存储在某个全局字段中。

    解决冲突
    如果双方都检测到更改,您的应用需要经过冲突解决流程。缺乏对正在同步的文件的理解的应用程序需要提示用户进行手动冲突解决,或者执行类似fork文件的操作,以便现在有两个副本。但是,处理自定义文件格式的应用程序应该具有足够的知识来有效地合并文件,而无需任何形式的用户交互。这需要显然完全取决于正在同步的文件。

    应用更改
    最后一步是将合并状态推送到需要的任何地方(例如,如果更改是本地的,则推送远程,如果更改是远程的,则推送本地,否则如果更改是在两个位置推送两个位置)。确保执行此步骤以避免替换“更改检测”步骤之后写入的内容非常重要。在本地,您可能通过在此过程中锁定文件来完成此操作,但是您无法使用远程文件执行此操作。相反,如果状态仍然是您所期望的,您将需要使用etag值来确保服务仅接受请求:

    await this.userDrive.Drive.Special.AppRoot.ItemWithPath(remotePath).Content.Request(new Option[] { new HeaderOption("If-Match", "etag") }).PutAsync(newContentStream);