我有一個c#UWP應用程序,它利用OneDrive API將文件存儲在approot
(僅適用於我的應用程序的特殊文件夾)中。我知道,我可以獲得OneDrive this way的總空間,但它沒有告訴我,我的應用需要多少空間。UWP OneDrive存儲空間
有沒有一種快速的方法來告訴我,應用程序需要多少空間來存儲這些文件(而不是迭代所有項目)?
我有一個c#UWP應用程序,它利用OneDrive API將文件存儲在approot
(僅適用於我的應用程序的特殊文件夾)中。我知道,我可以獲得OneDrive this way的總空間,但它沒有告訴我,我的應用需要多少空間。UWP OneDrive存儲空間
有沒有一種快速的方法來告訴我,應用程序需要多少空間來存儲這些文件(而不是迭代所有項目)?
正如Brad所說,approot
與任何其他OneDrive項目都有元數據一樣。並且在項目的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
)除外。
所以在大多數情況下,應用程序文件夾的eTag
不會改變,當我們使用UWP OneDrive .NET SDK或默認HttpClient
獲得app文件夾的元數據,我們將得到緩存的數據。爲了清楚地看到這一點,我們可以使用fiddler來跟蹤網絡,並且我們會在請求標頭中找到If-None-Match
,並且OneDrive的真實響應是HTTP 304 Not Modified
。
爲了解決這個問題,我們可以使用Windows.Web.Http.HttpClient
類HttpBaseProtocolFilter
類和HttpCacheControl
類禁用像以下緩存:
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()
。
當你取你的應用程序的文件夾(通過approot
)的size
屬性的值返回的項目應該是你的應用程序使用(因爲對一個文件夾值的大小之和的空間量的反映存儲在其中的所有文件,在任何級別)。
非常感謝,這是一個非常詳細的答案。 – user3079834