Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get file size properly and convert it to MB, GB in Cocoa? [duplicate]

Possible Duplicate:
ObjC/Cocoa class for converting size to human-readable string?

I'm new in Cocoa. I'm trying to get size of folder files properly. And display it in MB if it less 1 GB , or in GB.

The way I want it to display is rounded with one number after point.

Example 5.5 MB if it is more than 1000 > 1.1 GB

I'm trying to use this

 unsigned  long long size= ([[[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil] fileSize]);

But I can't a way properly convert number, and display it , as I want.

Thanks.

like image 330
User1234 Avatar asked Oct 21 '11 07:10

User1234


People also ask

How can I get MB file size?

format("The size of the file: %d bytes", fileSize); These methods will output the size in Bytes. So to get the MB size, you need to divide the file size from (1024*1024).

Which file is bigger GB or MB?

If you literally just want the answer to the question you just asked, there are 1024MB (megabytes) in one GB (gigabyte). If you want to know more there are 1024 gigabytes in a terabyte (TB) and 1024 terabytes in one petabyte (PB).

How do you convert GB to file size?

The quick and easy method to convert between size units To convert smaller units to larger units (convert bytes to kilobytes or megabytes) you simply divide the original number by 1,024 for each unit size along the way to the final desired unit.


3 Answers

For converting file size to MB, Gb use below function

- (id)transformedValue:(id)value
{
    
    double convertedValue = [value doubleValue];
    int multiplyFactor = 0;
    
    NSArray *tokens = @[@"bytes",@"KB",@"MB",@"GB",@"TB",@“PB”, @“EB”, @“ZB”, @“YB”];
    
    while (convertedValue > 1024) {
        convertedValue /= 1024;
        multiplyFactor++;
    }
    
    return [NSString stringWithFormat:@"%4.2f %@",convertedValue, tokens[multiplyFactor]];
}

EDIT:

You can also use NSByteCountFormatter class. Available in iOS 6.0 / OS X v10.8 and later.

[NSByteCountFormatter stringFromByteCount:1999 countStyle:NSByteCountFormatterCountStyleFile];

You can use NSByteCountFormatterCountStyleFile, NSByteCountFormatterCountStyleMemory, NSByteCountFormatterCountStyleDecimal or NSByteCountFormatterCountStyleBinary in countStyle.

NSByteCountFormatterCountStyleFile: Specifies display of file or storage byte counts. The actual behavior for this is platform-specific; on OS X 10.8, this uses the decimal style, but that may change over time.

NSByteCountFormatterCountStyleMemory: Specifies display of memory byte counts. The actual behavior for this is platform-specific; on OS X 10.8, this uses the binary style, but that may change over time.

NSByteCountFormatterCountStyleDecimal: Specifies the number of bytes for KB explicitly, 1000 bytes are shown as 1 KB

NSByteCountFormatterCountStyleBinary: Specifies the number of bytes for KB explicitly, 1024 bytes are shown as 1 KB

like image 108
Parag Bafna Avatar answered Oct 19 '22 23:10

Parag Bafna


If you're targeting OS X 10.8 or iOS 6, you can use NSByteCountFormatter.

I would write your example like this:

    NSError *error = nil;
    NSDictionary *attribs = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error];
    if (attribs) {
        NSString *string = [NSByteCountFormatter stringFromByteCount:[attribs fileSize] countStyle:NSByteCountFormatterCountStyleFile];
        NSLog(@"%@", string);
    }
like image 39
jrc Avatar answered Oct 20 '22 01:10

jrc


Here is a piece of code from my library. (I hereby release it under the simplified BSD license so there.) It is fairly extensively tested, and it does all the rounding exactly correct. This is not as trivial as it sounds. It always gives two significant figures unless it prints three digits (e.g., 980 B) in which case all three digits are significant.

Using stringWithFormat:@"%..something...f" won't work because if you round 999999 bytes up to 1000 kilobytes, you want to display it as 1.0 MB, not as 1000 kB.

Note that this code also does "banker's rounding" or "unbiased rounding" or "round to even", whichever you want to call it. So 1050 becomes "1.0 kB", but 1150 becomes "1.2 kB". This is the exact same way that printf does it on my system and is the generally preferred rounding method for this sort of thing.

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define SIZE_BUFSZ 7
static char const SIZE_PREFIXES[] = "kMGTPEZY";

void
format_size(char buf[SIZE_BUFSZ], uint64_t sz)
{
    int pfx = 0;
    unsigned int m, n, rem, hrem;
    uint64_t a;
    if (sz <= 0) {
        memcpy(buf, "0 B", 3);
        return;
    }
    a = sz;
    if (a < 1000) {
        n = a;
        snprintf(buf, SIZE_BUFSZ, "%u B", n);
        return;
    }
    for (pfx = 0, hrem = 0; ; pfx++) {
        rem = a % 1000ULL;
        a = a / 1000ULL;
        if (!SIZE_PREFIXES[pfx + 1] || a < 1000ULL)
            break;
        hrem |= rem;
    }
    n = a;
    if (n < 10) {
        if (rem >= 950) {
            buf[0] = '1';
            buf[1] = '0';
            buf[2] = ' ';
            buf[3] = SIZE_PREFIXES[pfx];
            buf[4] = 'B';
            buf[5] = '\0';
            return;
        } else {
            m = rem / 100;
            rem = rem % 100;
            if (rem > 50 || (rem == 50 && ((m & 1) || hrem)))
                m++;
            snprintf(buf, SIZE_BUFSZ,
                     "%u.%u %cB", n, m, SIZE_PREFIXES[pfx]);
        }
    } else {
        if (rem > 500 || (rem == 500 && ((n & 1) || hrem)))
            n++;
        if (n >= 1000 && SIZE_PREFIXES[pfx + 1]) {
            buf[0] = '1';
            buf[1] = '.';
            buf[2] = '0';
            buf[3] = ' ';
            buf[4] = SIZE_PREFIXES[pfx+1];
            buf[5] = 'B';
            buf[6] = '\0';
        } else {
            snprintf(buf, SIZE_BUFSZ,
                     "%u %cB", n, SIZE_PREFIXES[pfx]);
        }
    }
}

Here is the test data:

{ 0, "0 B" },
{ 5, "5 B" },
{ 20, "20 B" },
{ 100, "100 B" },
{ 500, "500 B" },
{ 999, "999 B" },
{ 1000, "1.0 kB" },
{ 1050, "1.0 kB" },
{ 1051, "1.1 kB" },
{ 2349, "2.3 kB" },
{ 2350, "2.4 kB" },
{ 9949, "9.9 kB" },
{ 9950, "10 kB" },
{ 10000, "10 kB" },
{ 10500, "10 kB" },
{ 10501, "11 kB" },
{ 99499, "99 kB" },
{ 99500, "100 kB" },
{ 999499, "999 kB" },
{ 999500, "1.0 MB" },
{ 1000000, "1.0 MB" },
{ 952500000, "952 MB" },
{ 952500001, "953 MB" },
{ 1000000000, "1.0 GB" },
{ 2300000000000ULL, "2.3 TB" },
{ 9700000000000000ULL, "9.7 PB" }
like image 44
Dietrich Epp Avatar answered Oct 20 '22 00:10

Dietrich Epp