64

In my iPhone app I am using the following code to find a file's size. Even though the file exists, I am seeing zero for the size. Can anyone help me? Thanks in advance.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *URL = [documentsDirectory stringByAppendingPathComponent:@"XML/Extras/Approval.xml"];

NSLog(@"URL:%@",URL);
NSError *attributesError = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:URL error:&attributesError];

int fileSize = [fileAttributes fileSize];
jscs
  • 62,161
  • 12
  • 145
  • 186
Kiran
  • 1,271
  • 3
  • 15
  • 25

5 Answers5

128

Try this;

NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:URL error:&attributesError];

NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long long fileSize = [fileSizeNumber longLongValue];

Note that the fileSize won't necessarily fit in an integer (especially a signed one) although you could certainly drop to a long for iOS as you'll never exceed that in reality. The example uses long long as in my code I have to be compatible with systems with much larger storage available.

Roger
  • 15,683
  • 3
  • 49
  • 73
  • 43
    Xcode 4.5+ one-liner: `long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil][NSFileSize] longLongValue]`. – mxcl Oct 23 '12 at 13:44
  • 8
    Better be `unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil][NSFileSize] unsignedLongLongValue]` because [`NSFileSize` is an **`unsigned`** `long long`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/nsfilemanager_Class/Reference/Reference.html#//apple_ref/doc/uid/20000305-SW2). – Pang Dec 09 '13 at 06:23
  • 14
    Can be written even shorter: `unsigned long long size = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize` – Erik Aigner Jun 16 '14 at 07:56
  • 2
    You can't send the URL as the Path parameter. You need to send `[URL path]` – Kenny Wyland Dec 06 '15 at 23:00
10

One liner in Swift:

let fileSize = try! NSFileManager.defaultManager().attributesOfItemAtPath(fileURL.path!)[NSFileSize]!.longLongValue
Krodak
  • 1,335
  • 10
  • 18
  • 4
    Updated for Swift 3: `let fileSize = try (FileManager.default.attributesOfItem(atPath: url.path)[.size] as! NSNumber).uint64Value` _or_ `let fileSize = try (FileManager.default.attributesOfItem(atPath: url.path) as NSDictionary).fileSize()` – Slipp D. Thompson Mar 25 '17 at 17:22
  • With Swift error handling.... `let fileSize = (try? FileManager.default.attributesOfItem(atPath: url.path))?[.size] as? Int ?? 0` – ekscrypto Dec 28 '17 at 20:58
6

If you have a URL (NSURL, not a String), you can get the file size without a FileManager:

 let attributes = try? myURL.resourceValues(forKeys: Set([.fileSizeKey]))
 let fileSize = attributes?.fileSize // Int?
kelin
  • 9,553
  • 6
  • 63
  • 92
3

Swift 4.x

do {
    let fileSize = try (FileManager.default.attributesOfItem(atPath: filePath) as NSDictionary).fileSize()
            print(fileSize)
    } catch let error {
            print(error)
    }
Hemang
  • 25,740
  • 17
  • 113
  • 171
1

Get the file size in MB Try This code for swift

func getSizeOfFile(withPath path:String) -> UInt64?
{
    var totalSpace : UInt64?

    var dict : [FileAttributeKey : Any]?

    do {
        dict = try FileManager.default.attributesOfItem(atPath: path)
    } catch let error as NSError {
         print(error.localizedDescription)
    }

    if dict != nil {
        let fileSystemSizeInBytes = dict![FileAttributeKey.systemSize] as! NSNumber

        totalSpace = fileSystemSizeInBytes.uint64Value
        return (totalSpace!/1024)/1024
    }
    return nil
}
Urvish Patel
  • 135
  • 1
  • 11