Posted on: June 24, 2021 05:01 PM
Posted by: Renato
Views: 686
Formato de bytes para quilobytes, megabytes, gigabytes
Cenário: o tamanho de vários arquivos é armazenado em um database como bytes. Qual é a melhor maneira de formatar essas informações de tamanho para quilobytes, megabytes e gigabytes? Por exemplo, eu tenho um MP3 que o Ubuntu exibe como “5.2 MB (5445632 bytes)”. Como eu exibiria isso em uma página da Web como “5.2 MB” E eu possuo arquivos com menos de um megabyte como KB e arquivos com um gigabyte e acima como GB?
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]; }
(Tirado do php.net , existem muitos outros exemplos, mas eu gosto deste melhor 🙂
Esta é a implementação de Chris Jester-Young, mais limpa que já vi, combinada com php.net e um argumento de precisão.
function formatBytes($size, $precision = 2) { $base = log($size, 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
Pseudo-código:
$base = log($size) / log(1024); $suffix = array("", "k", "M", "G", "T")[floor($base)]; return pow(1024, $base - floor($base)) . $suffix;
Esta é a implementação da Kohana , você poderia usá-la:
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]); }
Basta dividi-lo por 1024 para kb, 1024 ^ 2 para mb e 1024 ^ 3 para GB. Tão simples como isso.
use esta function se desejar um código curto
bcdiv ()
$size = 11485760; echo bcdiv($size, 1048576, 0); // return: 10 echo bcdiv($size, 1048576, 2); // return: 10,9 echo bcdiv($size, 1048576, 2); // return: 10,95 echo bcdiv($size, 1048576, 3); // return: 10,953
Apenas a minha alternativa, curta e limpa:
/** * @param int $bytes Number of bytes (eg. 25907) * @param int $precision [optional] Number of digits after the decimal point (eg. 1) * @return string Value converted with unit (eg. 25.3KB) */ function formatBytes($bytes, $precision = 2) { $unit = ["B", "KB", "MB", "GB"]; $exp = floor(log($bytes, 1024)) | 0; return round($bytes / (pow(1024, $exp)), $precision).$unit[$exp]; }
ou mais estúpido e eficiente:
function formatBytes($bytes, $precision = 2) { if ($bytes > pow(1024,3)) return round($bytes / pow(1024,3), $precision)."GB"; else if ($bytes > pow(1024,2)) return round($bytes / pow(1024,2), $precision)."MB"; else if ($bytes > 1024) return round($bytes / 1024, $precision)."KB"; else return ($bytes)."B"; }
Eu sei que talvez seja um pouco tarde para responder a esta pergunta, mas, mais dados não vão matar alguém. Aqui está uma function muito rápida:
function format_filesize($B, $D=2){ $S = 'BkMGTPEZY'; $F = floor((strlen($B) - 1) / 3); return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F].'B'; }
EDITAR: atualizei minha postagem para include a correção proposta pelo camomileCase:
function format_filesize($B, $D=2){ $S = 'kMGTPEZY'; $F = floor((strlen($B) - 1) / 3); return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F-1].'B'; }
Função simples
function formatBytes($size, $precision = 0){ $unit = ['Byte','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']; for($i = 0; $size >= 1024 && $i < count($unit)-1; $i++){ $size /= 1024; } return round($size, $precision).' '.$unit[$i]; } echo formatBytes('1876144', 2); //returns 1.79 MiB
Eu consegui com a seguinte function,
function format_size($size) { $mod = 1024; $units = explode(' ','B KB MB GB TB PB'); for ($i = 0; $size > $mod; $i++) { $size /= $mod; } return round($size, 2) . ' ' . $units[$i]; }
Minha abordagem
function file_format_size($bytes, $decimals = 2) { $unit_list = array('B', 'KB', 'MB', 'GB', 'PB'); if ($bytes == 0) { return $bytes . ' ' . $unit_list[0]; } $unit_count = count($unit_list); for ($i = $unit_count - 1; $i >= 0; $i--) { $power = $i * 10; if (($bytes >> $power) >= 1) return round($bytes / (1 << $power), $decimals) . ' ' . $unit_list[$i]; } }
function changeType($size, $type, $end){ $arr = ['B', 'KB', 'MB', 'GB', 'TB']; $tSayi = array_search($type, $arr); $eSayi = array_search($end, $arr); $pow = $eSayi - $tSayi; return $size * pow(1024 * $pow) . ' ' . $end; } echo changeType(500, 'B', 'KB');
Não sei por que você deve torná-lo tão complicado quanto os outros.
O código a seguir é muito mais simples de entender e cerca de 25% mais rápido do que as outras soluções que utilizam a function de log (a function 20 Mio. vezes com diferentes parâmetros)
function formatBytes($bytes, $precision = 2) { $units = ['Byte', 'Kilobyte', 'Megabyte', 'Gigabyte', 'Terabyte']; $i = 0; while($bytes > 1024) { $bytes /= 1024; $i++; } return round($bytes, $precision) . ' ' . $units[$i]; }
tente isso;)
function bytesToSize($bytes) { $sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if ($bytes == 0) return 'n/a'; $i = intval(floor(log($bytes) / log(1024))); if ($i == 0) return $bytes . ' ' . $sizes[$i]; return round(($bytes / pow(1024, $i)),1,PHP_ROUND_HALF_UP). ' ' . $sizes[$i]; } echo bytesToSize(10000050300);
function byte_format($size) { $bytes = array( ' KB', ' MB', ' GB', ' TB' ); foreach ($bytes as $val) { if (1024 <= $size) { $size = $size / 1024; continue; } break; } return round( $size, 1 ) . $val; }
Aqui está a implementação simplificada da function format_size do Drupal:
/** * Generates a string representation for the given byte count. * * @param $size * A size in bytes. * * @return * A string representation of the size. */ function format_size($size) { if ($size < 1024) { return $size . ' B'; } else { $size = $size / 1024; $units = ['KB', 'MB', 'GB', 'TB']; foreach ($units as $unit) { if (round($size, 2) >= 1024) { $size = $size / 1024; } else { break; } } return round($size, 2) . ' ' . $unit; } }
Está um pouco atrasado, mas uma versão um pouco mais rápida da resposta aceita está abaixo:
function formatBytes($bytes, $precision) { $unit_list = array ( 'B', 'KB', 'MB', 'GB', 'TB', ); $bytes = max($bytes, 0); $index = floor(log($bytes, 2) / 10); $index = min($index, count($unit_list) - 1); $bytes /= pow(1024, $index); return round($bytes, $precision) . ' ' . $unit_list[$index]; }
É mais eficiente, devido à realização de uma única operação log-2 em vez de duas operações log-e.
Na verdade, é mais rápido fazer a solução mais óbvia abaixo, porém:
function formatBytes($bytes, $precision) { $unit_list = array ( 'B', 'KB', 'MB', 'GB', 'TB', ); $index_max = count($unit_list) - 1; $bytes = max($bytes, 0); for ($index = 0; $bytes >= 1024 && $index < $index_max; $index++) { $bytes /= 1024; } return round($bytes, $precision) . ' ' . $unit_list[$index]; }
Isso ocorre porque, à medida que o índice é calculado ao mesmo tempo que o valor do número de bytes na unidade apropriada. Isso reduziu o tempo de execução em cerca de 35% (um aumento de velocidade de 55%).
Outra implementação condensada que pode se traduzir para a base 1024 (binária) ou base 1000 (decimal) e também funciona com números incrivelmente grandes, portanto, do uso da biblioteca bc:
function renderSize($byte,$precision=2,$mibi=true) { $base = (string)($mibi?1024:1000); $labels = array('K','M','G','T','P','E','Z','Y'); for($i=8;$i>=1;$i--) if(bccomp($byte,bcpow($base, $i))>=0) return bcdiv($byte,bcpow($base, $i), $precision).' '.$labels[$i-1].($mibi?'iB':'B'); return $byte.' Byte'; }
Eu pensei que eu adicionaria um código de dois submissores (Usando o código de John Himmelman, que está neste tópico, e usando o código de Eugene Kuzmenko ) que estou usando.
function swissConverter($value, $format = true, $precision = 2) { //Below converts value into bytes depending on input (specify mb, for //example) $bytes = preg_replace_callback('/^\s*(\d+)\s*(?:([kmgt]?)b?)?\s*$/i', function ($m) { switch (strtolower($m[2])) { case 't': $m[1] *= 1024; case 'g': $m[1] *= 1024; case 'm': $m[1] *= 1024; case 'k': $m[1] *= 1024; } return $m[1]; }, $value); if(is_numeric($bytes)) { if($format === true) { //Below converts bytes into proper formatting (human readable //basically) $base = log($bytes, 1024); $suffixes = array('', 'KB', 'MB', 'GB', 'TB'); return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)]; } else { return $bytes; } } else { return NULL; //Change to prefered response } }
Isso usa o código de Eugene para formatar o $value
em bytes (eu mantenho meus dados em MB, então ele converte meus dados: 10485760 MB
em 10995116277760
) – então usa o código de John para convertê-lo no valor de exibição apropriado ( 10995116277760
em 10 TB
) .
Descobriu isso realmente útil – então meus agradecimentos aos dois apresentadores!
Função extremamente simples para obter o tamanho do arquivo humano.
Fonte original: http://php.net/manual/de/function.filesize.php#106569
Copiar / colar código:
Desenvolvi minha própria function que converte o tamanho da memory legível para humanos em tamanhos diferentes.
function convertMemorySize($strval, string $to_unit = 'b') { $strval = strtolower(str_replace(' ', '', $strval)); $val = floatval($strval); $to_unit = strtolower(trim($to_unit))[0]; $from_unit = str_replace($val, '', $strval); $from_unit = empty($from_unit) ? 'b' : trim($from_unit)[0]; $units = 'kmgtph'; // (k)ilobyte, (m)egabyte, (g)igabyte and so on... // Convert to bytes if ($from_unit !== 'b') $val *= 1024 ** (strpos($units, $from_unit) + 1); // Convert to unit if ($to_unit !== 'b') $val /= 1024 ** (strpos($units, $to_unit) + 1); return $val; } convertMemorySize('1024Kb', 'Mb'); // 1 convertMemorySize('1024', 'k') // 1 convertMemorySize('5.2Mb', 'b') // 5452595.2 convertMemorySize('10 kilobytes', 'bytes') // 10240 convertMemorySize(2048, 'k') // By default convert from bytes, result is 2
Esta function aceita qualquer abreviatura de tamanho de memory como “Megabyte, MB, Mb, mb, m, kilobyte, K, KB, b, Terabyte, T …”, por isso é seguro de digitação.
function convertToReadableSize($size) { $base = log($size) / log(1024); $suffix = array("B", "KB", "MB", "GB", "TB"); $f_base = floor($base); return round(pow(1024, $base - floor($base)), 1) . $suffix[$f_base]; }
Basta chamar a function
echo convertToReadableSize(1024); // Outputs '1KB' echo convertToReadableSize(1024 * 1024); // Outputs '1MB'
- https://php.docow.com/formato-de-bytes-para-quilobytes-megabytes-gigabytes.html
- https://stackoverflow.com/questions/2510434/format-bytes-to-kilobytes-megabytes-gigabytes
Donate to Site
Renato
Developer
-
Renato Lucena - há 3 anos
```PHP <?php function TamDown($Url) { $N = array('Bytes','KB','MB','GB'); $Tam = filesize($Url); for ($Pos=0;$Tam>=1024;$Pos++) { $Tam /= 1024; } return @round($Tam,2)." ".$N[$Pos]; } ?> ```