如何正确获取文件大小并将其转换为MB,GB在Cocoa?
可能重复:
ObjC / Cocoa类将大小转换为可读的string?
我是cocoa的新手 我试图正确地获取文件夹文件的大小。 如果小于1 GB或GB,则以MB显示。
我希望它显示的方式是在一个点之后用一个数字四舍五入。
例如5.5 MB,如果它大于1000> 1.1 GB
我正在尝试使用这个
unsigned long long size= ([[[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil] fileSize]);
但我不能正确地转换数字,并按我的意思显示它。
谢谢。
为了将文件大小转换为MB,Gb使用下面的函数
- (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]]; }
编辑:
你也可以使用NSByteCountFormatter类。 适用于iOS 6.0 / OS X v10.8及更高版本。
[NSByteCountFormatter stringFromByteCount:1999 countStyle:NSByteCountFormatterCountStyleFile];
您可以在countStyle中使用NSByteCountFormatterCountStyleFile
, NSByteCountFormatterCountStyleMemory
, NSByteCountFormatterCountStyleDecimal
或NSByteCountFormatterCountStyleBinary。
NSByteCountFormatterCountStyleFile :指定文件或存储字节数的显示。 实际的行为是针对平台的; 在OS X 10.8上,这使用小数点样式,但是可能随时间而改变。
NSByteCountFormatterCountStyleMemory :指定显示内存字节数。 实际的行为是针对平台的; 在OS X 10.8上,这使用了二进制样式,但是可能随时间而改变。
NSByteCountFormatterCountStyleDecimal :明确指定KB的字节数,1000字节显示为1 KB
NSByteCountFormatterCountStyleBinary :明确指定KB的字节数,1024字节显示为1 KB
如果您的目标是OS X 10.8或iOS 6,则可以使用NSByteCountFormatter 。
我会写这样的例子:
NSError *error = nil; NSDictionary *attribs = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error]; if (attribs) { NSString *string = [NSByteCountFormatter stringFromByteCount:[attribs fileSize] countStyle:NSByteCountFormatterCountStyleFile]; NSLog(@"%@", string); }
这里是我的图书馆的一段代码。 (我特此在简化的BSD许可证下释放它)。它经过了相当广泛的testing,它完全正确。 这不像听起来那么微不足道。 它总是给出两个有效数字,除非它打印三位数字(例如,980 B),在这种情况下,所有三位数字都是重要的。
使用stringWithFormat:@"%..something...f"
将不起作用,因为如果将999999字节舍入到1000千字节,则要将其显示为1.0 MB,而不是1000 kB。
请注意,这个代码也是“银行家舍入”或者“无偏舍入”或者“舍入舍入”,无论你想怎么称呼它。 所以1050变成“1.0 kB”,而1150变成“1.2 kB”。 这与printf
在我的系统上完全相同,并且是这种types的一般首选舍入方法。
#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]); } } }
这里是testing数据:
{ 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" }