tags:

views:

516

answers:

6

Scenario: the size of various files are stored in a database as bytes. What's the best way to format this size info to kilobytes, megabytes and gigabytes? For instance I have an MP3 that Ubuntu displays as "5.2 MB (5445632 bytes)". How would I display this on a web page as "5.2 MB" AND have files less than one megabyte display as KB and files one gigabyte and above display as GB?

A: 

Just divide it by 1024 for kb, 1024^2 for mb and 1024^3 for GB. As simple as that.

Vafello
+2  A: 

This is Kohana's implementation, you could use it:

public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE)
{
    // Format string
    $format = ($format === NULL) ? '%01.2f %s' : (string) $format;

    // IEC prefixes (binary)
    if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE)
    {
        $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
        $mod   = 1024;
    }
    // SI prefixes (decimal)
    else
    {
        $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
        $mod   = 1000;
    }

    // Determine unit to use
    if (($power = array_search((string) $force_unit, $units)) === FALSE)
    {
        $power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0;
    }

    return sprintf($format, $bytes / pow($mod, $power), $units[$power]);
}
ryeguy
+4  A: 
function formatBytes($bytes, $precision = 2) { 
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 

    $bytes = max($bytes, 0); 
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
    $pow = min($pow, count($units) - 1); 

    // Uncomment one of the following alternatives
    // $bytes /= pow(1024, $pow);
    // $bytes /= (1 << (10 * $pow)); 

    return round($bytes, $precision) . ' ' . $units[$pow]; 
} 

(Taken from php.net, there are many other examples there, but I like this one best :-)

Mef
I almost upvoted your answer (it's very similar to mine), but I don't like this "division by 1024^$pow" business. You should just do 1024^fraction($pow) and be done. :-)
Chris Jester-Young
If you used `$bytes /= (1 << (10 * $pow))` or the like, I could like it better. :-P
Chris Jester-Young
There you go :D (personally, I don't like bitwise arithmetic, because it is hard to understand if you aren't used to it...)
Mef
@Mef: Nice, nice. +1 :-)
Chris Jester-Young
A: 

Check out the filesize function comments, especially this one: a quick way to convert bytes to a more readable format

erenon
+1  A: 

Pseudocode:

$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
Chris Jester-Young
A: 

This is Chris Jester-Young's implementation, cleanest I've ever seen, combined with php.net's and a precision argument.

function formatBytes($size, $precision = 2)
{
    $base = log($size) / log(1024);
    $suffixes = array('', 'k', 'M', 'G', 'T');   

    return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
}

echo formatBytes(24962496);
// 23.81M

echo formatBytes(24962496, 0);
// 24M

echo formatBytes(24962496, 4);
// 23.8061M
John Himmelman