UWP OneDrive 存储 space
UWP OneDrive storage space
我有一个 c# UWP 应用程序,它使用 OneDrive API to store files in the approot
(special folder for my App only). I know, that I can get the total space of OneDrive this way,但它没有告诉我,我的应用程序需要多少 space。
有没有一种快速的方法可以告诉我,我的应用需要多少 space 来存储这些文件(而不是遍历所有项目)?
当您获取应用的文件夹(通过 approot
)时,项目返回的 size
属性 的值应该反映 space 的数量您的应用程序正在使用(因为对于文件夹而言,该值是其中存储的任何级别的所有文件大小的总和)。
正如 Brad 所说,approot
与任何其他 OneDrive 项目一样具有元数据。在项目的 metadata 中有一个 size
属性 表示项目的大小(以字节为单位)。因此,我们可以使用此 属性 来获取您的应用所占用的总 space。
作为App Folder described, we can use GET /drive/special/approot
to get your app folder's metadata and when using 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 将 return 与您第一次 运行 相同的值。
这是因为虽然 Get metadata for a OneDrive item,它有一个可选的请求 headers if-none-match
,如果包含此请求 header 并提供了 eTag(或 cTag)匹配文件上的当前标签,HTTP 304 Not Modified
响应是 returned。
而在UWP中,使用HttpClient
会自动在请求中添加这个header,如果eTag
没有改变,HttpClient
将不会得到最新的信息,它将 return 它缓存的数据。根据Item resource type:
Note: The eTag
and cTag
properties work differently on containers (folders). The cTag
value is modified when content or metadata of any descendant of the folder is changed. The eTag
value is only modified when the folder's properties are changed, except for properties that are derived from descendants (like childCount
or lastModifiedDateTime
).
所以在大多数情况下,app文件夹的eTag
是不会改变的,当我们使用OneDrive .NET SDK or default HttpClient
in UWP to get app folder's metadata, we will get the cached data. To see this clearly, we can use fiddler来跟踪网络时,我们会发现在请求header中,If-None-Match
添加,OneDrive 的真实响应是 HTTP 304 Not Modified
。
为了解决这个问题,我们可以使用 Windows.Web.Http.HttpClient
class with HttpBaseProtocolFilter
class and HttpCacheControl
class 来禁用缓存,如下所示:
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()
我有一个 c# UWP 应用程序,它使用 OneDrive API to store files in the approot
(special folder for my App only). I know, that I can get the total space of OneDrive this way,但它没有告诉我,我的应用程序需要多少 space。
有没有一种快速的方法可以告诉我,我的应用需要多少 space 来存储这些文件(而不是遍历所有项目)?
当您获取应用的文件夹(通过 approot
)时,项目返回的 size
属性 的值应该反映 space 的数量您的应用程序正在使用(因为对于文件夹而言,该值是其中存储的任何级别的所有文件大小的总和)。
正如 Brad 所说,approot
与任何其他 OneDrive 项目一样具有元数据。在项目的 metadata 中有一个 size
属性 表示项目的大小(以字节为单位)。因此,我们可以使用此 属性 来获取您的应用所占用的总 space。
作为App Folder described, we can use GET /drive/special/approot
to get your app folder's metadata and when using 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 将 return 与您第一次 运行 相同的值。
这是因为虽然 Get metadata for a OneDrive item,它有一个可选的请求 headers if-none-match
,如果包含此请求 header 并提供了 eTag(或 cTag)匹配文件上的当前标签,HTTP 304 Not Modified
响应是 returned。
而在UWP中,使用HttpClient
会自动在请求中添加这个header,如果eTag
没有改变,HttpClient
将不会得到最新的信息,它将 return 它缓存的数据。根据Item resource type:
Note: The
eTag
andcTag
properties work differently on containers (folders). ThecTag
value is modified when content or metadata of any descendant of the folder is changed. TheeTag
value is only modified when the folder's properties are changed, except for properties that are derived from descendants (likechildCount
orlastModifiedDateTime
).
所以在大多数情况下,app文件夹的eTag
是不会改变的,当我们使用OneDrive .NET SDK or default HttpClient
in UWP to get app folder's metadata, we will get the cached data. To see this clearly, we can use fiddler来跟踪网络时,我们会发现在请求header中,If-None-Match
添加,OneDrive 的真实响应是 HTTP 304 Not Modified
。
为了解决这个问题,我们可以使用 Windows.Web.Http.HttpClient
class with HttpBaseProtocolFilter
class and HttpCacheControl
class 来禁用缓存,如下所示:
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()