I have an Windows 8.1 Store App. I am trying to find the Local Folder Size.?(e.g. 210 MB)
I have an application which would download some of content into my local folder. I want to check the size of my local folder (such as how many MB are currently there).
I have tried looking through MSDN and Google but haven't been able to find anything on it.
Note : I have a folder and subfolder so not only files which is in local folder..
You are able to access the LocalFolder
via the ApplicationData.LocalFolder
property.
This LocalFolder
is a StorageFolder
object. StorageFolder
has a method called GetBasicPropertiesAsync
.
GetBasicPropertiesAsync
returns a BasicProperties
object. This BasicProperties
object has a Size
property which tells you the size of the item in question (folder or file). I believe that Size
is in bytes (a ulong
).
The complete command can be done in a single line in an async
method like this:
(await ApplicationData.LocalFolder.GetBasicPropertiesAsync()).Size;
You can also split up each step if you need any other information.
Edit: Apparently this does not work as well as hoped. The solution is to create a query and sum up all of the files. You can do this using Linq.
using System.Linq;
// Query all files in the folder. Make sure to add the CommonFileQuery
// So that it goes through all sub-folders as well
var folders = ApplicationData.LocalFolder.CreateFileQuery(CommonFileQuery.OrderByName);
// Await the query, then for each file create a new Task which gets the size
var fileSizeTasks = (await folders.GetFilesAsync()).Select(async file => (await file.GetBasicPropertiesAsync()).Size);
// Wait for all of these tasks to complete. WhenAll thankfully returns each result
// as a whole list
var sizes = await Task.WhenAll(fileSizeTasks);
// Sum all of them up. You have to convert it to a long because Sum does not accept ulong.
var folderSize = sizes.Sum(l => (long) l);
The C# solution is fine for small-medium size folders but if your app (for whatever reason) has large amount of files this method will take a lot of time and you may even run out of memory. I ran into this situation and opted to write a c++ winrt component that gets the size of a folder and I can attest that it runs much faster and with less memory. The code for the function is below, in the c# code you can call GetAppUsedSpace using the LocalState folder's Path property.
#include "pch.h"
#include "NativeFileHelper.h"
#include <string>
#include <vector>
#include <stack>
#include <iostream>
#include <windows.h>
using namespace Platform;
NativeFileHelper::NativeFileHelper()
{
}
unsigned __int64 ListFiles(std::wstring path, std::wstring mask) {
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
std::wstring spec;
std::stack<std::wstring> directories;
directories.push(path);
unsigned __int64 result = 0;
while (!directories.empty()) {
path = directories.top();
spec = path + L"\\" + mask;
directories.pop();
hFind = FindFirstFileEx(spec.c_str(), FindExInfoStandard, &ffd, FINDEX_SEARCH_OPS::FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);
if (hFind == INVALID_HANDLE_VALUE) {
return result;
}
do {
if (wcscmp(ffd.cFileName, L".") != 0 &&
wcscmp(ffd.cFileName, L"..") != 0) {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
directories.push(path + L"\\" + ffd.cFileName);
}
else {
//This is file name
result += ffd.nFileSizeLow + (ffd.nFileSizeHigh * MAXDWORD);
//files.push_back(path + "\\" + ffd.cFileName);
}
}
} while (FindNextFile(hFind, &ffd) != 0);
if (GetLastError() != ERROR_NO_MORE_FILES) {
FindClose(hFind);
return result;
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
return result;
}
unsigned __int64 NativeFileHelper::GetAppUsedSpace(Platform::String^ pathOfFolder)
{
unsigned __int64 size = ListFiles(pathOfFolder->Data(), L"*");
return size;
}