views:

217

answers:

4

Hello there!

I'm trying to figure out how to convert a file's (or directory's) byte size into kilobytes, megabytes, gigabytes, etc... respectively according the file's or directory's size so that is matches what the Finder displays in the panel when you hit "Get Info".

The byte size I get perfectly matches the byte size as reported in Finder, but I can't figure out how to get the file's size (as displayed by the Finder in KB, MB, GB, etc) to match.

I know in 10.6 we use base 10, so a kilobyte is 1000 bytes and not 1024, but dividing the byte count by 1000 (or 1000^2, 1000^3, etc) doesn't match what the Finder reports.

For instance, in the Finder: a 330-byte text file is displayed as a 4KB file (so my initial guess would be to round-up all file sizes to 4KB figures), but 389,022-byte directory is displayed as a 418KB (way more than rounding-up to 4KB, so my guess is wrong). Also a 1,315,291,136-byte file is displayed as 1.33GB.

So can anyone please be so kind as to shed some light here? How are these figures calculated? I've looked all around and haven't been able to find an answer.

Thanks in advance for your help!

P.S. I've always been 100% Cocoa-oriented since I started programming and I've never used the Carbon framework before (I know it's very powerful, I just don't know how to use it). I mention this just in case anyone wants to give me a Carbon solution assuming I know how to use it. I don't.

+1  A: 

The file is 4 KB because that is the default block size of the HFS+ formatted drive. No file can be smaller than 4 KB. I suspect that is why your directory is a lot more than rounding up to 4 KB, since every smaller file in that directory is already "rounded up" to 4KB chunks, added together the difference may indeed be substantial.

As for your 1,315,291,136-byte showing up as 1.33GB -- is it really a monolithic file? Many files in the finder, for example applications, are actually a directory of many smaller files abstracted in the finder. If you open a contextual menu on the file (right click) do you see "Show Package Contents" as an option?

ghoppe
+5  A: 

In HFS+ each file will occupy a multiple of 4,096 bytes (the "block size").

If your directory contains one thousand 1-byte files, the total size occupied by the directory would be

(1000 * 4,096) = 4,096,000 = 4.1 MB,

although the number of bytes used by the directory is still

1 * 1000 = 1,000 bytes.
KennyTM
+1  A: 

You're probably not measuring a resource fork. You'll need to use the Core Services File Manager both to iterate the directories and to measure the sizes of files. Unlike NSFileManager, the File Manager will tell you the size of the resource fork.

Peter Hosey
A: 

You can use my NSValueTransformer subclass if you like:

@interface FileSizeTransformer : NSValueTransformer {

}

+ (Class)transformedValueClass;
+ (BOOL)allowsReverseTransformation;
- (id)transformedValue:(id)value;

@end

@implementation FileSizeTransformer
+ (Class)transformedValueClass;
{
    return [NSString class];
}

+ (BOOL)allowsReverseTransformation;
{
    return NO;
}
- (id)transformedValue:(id)value;
{
    if (![value isKindOfClass:[NSNumber class]])
        return nil;

    double convertedValue = [value doubleValue];
    int multiplyFactor = 0;

    NSArray *tokens = [NSArray arrayWithObjects:@"B",@"KB",@"MB",@"GB",@"TB",nil];

    while (convertedValue > 1024) {
        convertedValue /= 1024;
        multiplyFactor++;
    }

    return [NSString stringWithFormat:@"%4.2f %@",convertedValue, [tokens objectAtIndex:multiplyFactor],value];
}

@end
Diederik Hoogenboom