首页 文章

UWP OneDrive存储空间

提问于
浏览
0

我有一个c#UWP应用程序,它使用OneDrive API来存储 approot (仅适用于我的应用程序的特殊文件夹)中的文件 . 我知道,我可以获得OneDrive this way的总空间,但它没有告诉我,我的应用程序需要多少空间 .

有没有一种快速的方法来告诉我的应用程序在那里存储这些文件需要多少空间(而不是遍历所有项目)?

2 回答

  • 1

    正如Brad所说, approot 与任何其他OneDrive项目一样,都有元数据 . 在item的metadata中有一个 size 属性,表示项目的大小(以字节为单位) . 因此,我们可以使用此属性来获取应用占用的总空间 .

    App Folder所述,我们可以使用 GET /drive/special/approot 来获取您的应用文件夹的元数据,当使用OneDrive .NET SDK时,代码将如下:

    var item = await oneDriveClient.Drive.Special.AppRoot.Request().GetAsync();
    System.Diagnostics.Debug.WriteLine($"{item.Name}'s size is {item.Size}");
    

    但是,正如我测试的那样,当我们在UWP中使用此代码时,我们将遇到缓存问题 . 即使您的应用程序文件夹的大小已更改,此API将返回与您第一次运行它时相同的值 .

    这是因为在Get metadata for a OneDrive item时,它有一个可选的请求头 if-none-match ,如果包含此请求头并且提供的eTag(或cTag)与文件上的当前标记匹配,则返回 HTTP 304 Not Modified 响应 .

    在UWP中,使用 HttpClient 将自动在请求中添加此标头,如果 eTag 未更改, HttpClient 将无法获取最新信息,它将返回缓存的数据 . 根据Item resource type

    注意:eTag和cTag属性在容器(文件夹)上的工作方式不同 . 当文件夹的任何后代的内容或元数据发生更改时,将修改cTag值 . 仅当文件夹的属性发生更改时才会修改eTag值,但从后代(如childCount或lastModifiedDateTime)派生的属性除外 .

    所以在大多数情况下,app文件夹 eTag 不会改变,当我们在UWP中使用OneDrive .NET SDK或默认 HttpClient 来获取app文件夹的元数据时,我们将获得缓存数据 . 为了清楚地看到这一点,我们可以使用fiddler来跟踪网络,我们会在请求 Headers 中找到 If-None-Match ,OneDrive的真实响应是 HTTP 304 Not Modified .
    enter image description here

    要解决此问题,我们可以使用带有HttpBaseProtocolFilter class和HttpCacheControl类的Windows.Web.Http.HttpClient类来禁用缓存,如下所示:

    var oneDriveClient = await OneDriveClientExtensions.GetAuthenticatedUniversalClient(new[] { "wl.signin", "onedrive.readwrite" });
    
    var filter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
    filter.CacheControl.ReadBehavior = Windows.Web.Http.Filters.HttpCacheReadBehavior.MostRecent;
    filter.CacheControl.WriteBehavior = Windows.Web.Http.Filters.HttpCacheWriteBehavior.NoCache;
    
    var httpClient = new HttpClient(filter);
    
    var request = new HttpRequestMessage(HttpMethod.Get, new Uri("https://api.onedrive.com/v1.0/drive/special/approot"));
    request.Headers.Authorization = new Windows.Web.Http.Headers.HttpCredentialsHeaderValue("Bearer", oneDriveClient.AuthenticationProvider.CurrentAccountSession.AccessToken);
    
    var response = await httpClient.SendRequestAsync(request);
    
    var item = oneDriveClient.HttpProvider.Serializer.DeserializeObject<Item>(await response.Content.ReadAsStringAsync());
    System.Diagnostics.Debug.WriteLine($"{item.Name}'s size is {item.Size}");
    

    PS: 要使此方法有效,我们需要确保没有本地HTTP缓存 . 所以我们最好先卸载应用程序,不要在应用程序中使用 await oneDriveClient.Drive.Special.AppRoot.Request().GetAsync() .

  • 2

    当您获取应用程序的文件夹(通过 approot )时,项目上返回的 size 属性的值应该反映应用程序正在使用的空间量(因为对于文件夹,该值是存储的所有文件大小的总和在其中,任何级别) .

相关问题