5

I'm storing files in a local documents directory, separated by folders. Is there an easy way for me to get the file size of the contents of the documents directory and all subdirectories on an iPhone?

I can manually iterate over folders and keep adding file size, but I'm hoping there's something cleaner and more efficient.

Thank you !

Cyrille
  • 25,014
  • 12
  • 67
  • 90
Alex Stone
  • 46,408
  • 55
  • 231
  • 407
  • 1
    Calculating the size that a directory takes up on disk is actually a little more involved. Find out how to in [this answer](http://stackoverflow.com/a/28660040/104790) to a similar question. – Nikolai Ruhe Feb 23 '15 at 08:45

2 Answers2

5

The approach and efficiency vary depends on the iOS version. For iOS 4.0 and later you can make a category on NSFileManager with something like this:

- (unsigned long long)contentSizeOfDirectoryAtURL:(NSURL *)directoryURL
{
    unsigned long long contentSize = 0;
    NSDirectoryEnumerator *enumerator = [self enumeratorAtURL:directoryURL includingPropertiesForKeys:[NSArray arrayWithObject:NSURLFileSizeKey] options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:NULL];
    NSNumber *value = nil;
    for (NSURL *itemURL in enumerator) {
        if ([itemURL getResourceValue:&value forKey:NSURLFileSizeKey error:NULL]) {
            contentSize += value.unsignedLongLongValue;
        }
    }
    return contentSize;
}
voromax
  • 3,369
  • 2
  • 30
  • 53
5

You can recursively go over all folders and get the size. Like this:

+(NSUInteger)getDirectoryFileSize:(NSURL *)directoryUrl
{
    NSUInteger result = 0;
    NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey,
                           NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey, nil];

    NSArray *array = [[NSFileManager defaultManager]
                      contentsOfDirectoryAtURL:directoryUrl
                      includingPropertiesForKeys:properties
                      options:(NSDirectoryEnumerationSkipsHiddenFiles)
                      error:nil];

    for (NSURL *fileSystemItem in array) {
        BOOL directory = NO;
        [[NSFileManager defaultManager] fileExistsAtPath:[fileSystemItem path] isDirectory:&directory];
        if (!directory) {
            result += [[[[NSFileManager defaultManager] attributesOfItemAtPath:[fileSystemItem path] error:nil] objectForKey:NSFileSize] unsignedIntegerValue];
        }
        else {
            result += [CacheManager getDirectoryFileSize:fileSystemItem];
        }
    }

    return result;
}
Dmytro Mykhailov
  • 249
  • 1
  • 3
  • 14