ObjC / Cocoa类将大小转换为人类可读的字符串? [英] ObjC/Cocoa class for converting size to human-readable string?

查看:107
本文介绍了ObjC / Cocoa类将大小转换为人类可读的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个简单的方法来做类似的事情。

  [NSMagicDataConverter humanStringWithBytes:20000000] 



..会返回19.1MB?

方案

这是我自己的问题:

 枚举{
kUnitStringBinaryUnits = 1< ;& 0,
kUnitStringOSNativeUnits = 1<< 1,
kUnitStringLocalizedFormat = 1<< 2
};

NSString * unitStringFromBytes(double bytes,uint8_t flags){

static const char units [] = {'\0','k','M' G','T','P','E','Z','Y'};
static int maxUnits = sizeof units - 1;

int multiplier =(flags& kUnitStringOSNativeUnits&&!leopardOrGreater()|| flags& kUnitStringBinaryUnits)? 1024:1000;
int exponent = 0;

while(bytes> = multiplier&&& exponent< maxUnits){
bytes / = multiplier;
exponent ++;
}
NSNumberFormatter * formatter = [[[NSNumberFormatter alloc] init] autorelease];
[formatter setMaximumFractionDigits:2];
if(flags& kUnitStringLocalizedFormat){
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
}
//注意重用这个格式字符串。 - [NSString stringWithFormat]忽略\0,* printf不。
return [NSString stringWithFormat:@%@%cB,[formatter stringFromNumber:[NSNumber numberWithDouble:bytes]],units [exponent]];
}

默认情况下(如果 0 flags )传递c>,它将输出SI单位(十进制)。您可以设置 kUnitStringBinaryUnits 选择适合内存的二进制(基本2)单元,或 kUnitStringOSNativeUnits 自动基于操作系统版本(pre-Leopard获取基础二,post-Leopard获取基础十)。设置 kUnitStringLocalizedFormat 根据用户的当前语言环境格式化字符串。例如:

  unitStringFromBytes(1073741824,0); //→1.07 GB
unitStringFromBytes(1073741824,kUnitStringBinaryUnits); //→1 GB
unitStringFromBytes(1073741824,kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); //→1.07 GB(在Mac OS 10.6中)
unitStringFromBytes(12345678901234567890123456789,kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); //→12,345.68 YB(在Mac OS 10.6中,在美国)
unitStringFromBytes(12345678901234567890123456789,kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); //→12.345,68 YB(在Mac OS 10.6中,在西班牙)






这是OS本地单元所需的帮助函数:

  BOOL leopardOrGreater(){
static BOOL alreadyComputedOS = NO;
static BOOL leopardOrGreater = NO;
if(!alreadyComputedOS){
SInt32 majorVersion,minorVersion;
Gestalt(gestaltSystemVersionMajor,& majorVersion);
Gestalt(gestaltSystemVersionMinor,& minorVersion);
leopardOrGreater =((majorVersion == 10&& minorVersion> = 5)|| majorVersion> 10);
alreadyComputedOS = YES;
}
return leopardOrGreater;
}


Is there a simple way to do something like..

[NSMagicDataConverter humanStringWithBytes:20000000]

..which would return "19.1MB"?

解决方案

Here's my own take on the problem:

enum {
    kUnitStringBinaryUnits     = 1 << 0,
    kUnitStringOSNativeUnits   = 1 << 1,
    kUnitStringLocalizedFormat = 1 << 2
};

NSString* unitStringFromBytes(double bytes, uint8_t flags){

    static const char units[] = { '\0', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
    static int maxUnits = sizeof units - 1;

    int multiplier = (flags & kUnitStringOSNativeUnits && !leopardOrGreater() || flags & kUnitStringBinaryUnits) ? 1024 : 1000;
    int exponent = 0;

    while (bytes >= multiplier && exponent < maxUnits) {
        bytes /= multiplier;
        exponent++;
    }
    NSNumberFormatter* formatter = [[[NSNumberFormatter alloc] init] autorelease];
    [formatter setMaximumFractionDigits:2];
    if (flags & kUnitStringLocalizedFormat) {
        [formatter setNumberStyle: NSNumberFormatterDecimalStyle];
    }
    // Beware of reusing this format string. -[NSString stringWithFormat] ignores \0, *printf does not.
    return [NSString stringWithFormat:@"%@ %cB", [formatter stringFromNumber: [NSNumber numberWithDouble: bytes]], units[exponent]];
}

By default (if 0 is passed for flags), it will output SI units (base ten). You can set kUnitStringBinaryUnits to select binary (base two) units suitable for memory, or kUnitStringOSNativeUnits to have the unit type selected automatically based on OS version (pre-Leopard gets base two, post-Leopard gets base ten). Setting kUnitStringLocalizedFormat formats the string based on the user's current locale. For example:

unitStringFromBytes(1073741824, 0); // → "1.07 GB"
unitStringFromBytes(1073741824, kUnitStringBinaryUnits); // → "1 GB"
unitStringFromBytes(1073741824, kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); // → "1.07 GB" (In Mac OS 10.6)
unitStringFromBytes(12345678901234567890123456789, kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); // → "12,345.68 YB" (In Mac OS 10.6, in the US)
unitStringFromBytes(12345678901234567890123456789, kUnitStringOSNativeUnits | kUnitStringLocalizedFormat); // → "12.345,68 YB" (In Mac OS 10.6, in Spain)


Here's the helper function required for OS-native units:

BOOL leopardOrGreater(){
    static BOOL alreadyComputedOS = NO;
    static BOOL leopardOrGreater = NO;
    if (!alreadyComputedOS) {
        SInt32 majorVersion, minorVersion;
        Gestalt(gestaltSystemVersionMajor, &majorVersion);
        Gestalt(gestaltSystemVersionMinor, &minorVersion);
        leopardOrGreater = ((majorVersion == 10 && minorVersion >= 5) || majorVersion > 10);
        alreadyComputedOS = YES;
    }
    return leopardOrGreater;
}

这篇关于ObjC / Cocoa类将大小转换为人类可读的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆