【问题标题】:PHP filesize MB/KB conversion [duplicate]PHP文件大小MB / KB转换[重复]
【发布时间】:2011-07-26 23:08:06
【问题描述】:

如何将 PHP 的 filesize() 函数的输出转换为具有兆字节、千字节等的良好格式?

喜欢:

  • 如果大小小于 1 MB,则以 KB 显示大小
  • 如果它在 1 MB - 1 GB 之间,则以 MB 为单位显示
  • 如果更大 - 以 GB 为单位

【问题讨论】:

标签: php file filesize


【解决方案1】:

这是一个示例:

<?php
// Snippet from PHP Share: http://www.phpshare.org

    function formatSizeUnits($bytes)
    {
        if ($bytes >= 1073741824)
        {
            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
        }
        elseif ($bytes >= 1048576)
        {
            $bytes = number_format($bytes / 1048576, 2) . ' MB';
        }
        elseif ($bytes >= 1024)
        {
            $bytes = number_format($bytes / 1024, 2) . ' KB';
        }
        elseif ($bytes > 1)
        {
            $bytes = $bytes . ' bytes';
        }
        elseif ($bytes == 1)
        {
            $bytes = $bytes . ' byte';
        }
        else
        {
            $bytes = '0 bytes';
        }

        return $bytes;
}
?>

【讨论】:

  • 这个答案比下面的其他答案更有效。它避免了使用日志函数或连续除法语句来识别单元。
  • 这是一个绝妙的解决方案,感谢您提供了这个很棒的功能 - 正是我想要的。
  • 美丽。谢谢。
  • 不错的一个。坚持下去
  • 这个函数其实是不正确的。 1KB 是 1000Bytes,因为 Kilo 是 1000。
【解决方案2】:

更简洁的方法:

function Size($path)
{
    $bytes = sprintf('%u', filesize($path));

    if ($bytes > 0)
    {
        $unit = intval(log($bytes, 1024));
        $units = array('B', 'KB', 'MB', 'GB');

        if (array_key_exists($unit, $units) === true)
        {
            return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
        }
    }

    return $bytes;
}

【讨论】:

  • 这看起来更简洁,但使用日志来识别单位比使用一些简单的不等式要昂贵得多。
  • @AliGangji:确实,准确地说,成本要高出 0.1% 到 42%(取决于 if 条件 $bytes 属于哪个条件)。
  • @AliGangji:为了扩展我的最后一条评论,对于 但是 对于 1024 及以上我得到一致的平均值约为 0.1%。有趣!
  • @AlixAxel 不是这样,因为 PHP 解析器会分析 if 块自下而上,即从单个(最后一个)else 开始,向上遍历所有 elseif,直到最后到达第一个(按顺序)if?只是徘徊,为什么会得到这样的结果?
  • 我简直不敢相信你们在这个更简洁、更优雅的答案中争论对数方程的“成本”。你是如何衡量这种差异的?而且,如果日志成本如此之高,为什么不在应用单元附录之前以 >= 1024 的比较开始函数?
【解决方案3】:

一个完整的例子。

<?php
    $units = explode(' ','B KB MB GB TB PB');
    echo("<html><body>");
    echo('file size: ' . format_size(filesize("example.txt")));
    echo("</body></html>");


    function format_size($size) {

        $mod = 1024;

        for ($i = 0; $size > $mod; $i++) {
            $size /= $mod;
        }

        $endIndex = strpos($size, ".")+3;

        return substr( $size, 0, $endIndex).' '.$units[$i];
    }
?>

【讨论】:

    【解决方案4】:

    更好的是我从a plugin创建的这个版本我发现:

    function filesize_formatted($path)
    {
        $size = filesize($path);
        $units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
        $power = $size > 0 ? floor(log($size, 1024)) : 0;
        return number_format($size / pow(1024, $power), 2, '.', ',') . ' ' . $units[$power];
    }
    

    filesize() doc的备注

    因为 PHP 的整数类型是有符号的,而且很多平台使用 32bit 整数,某些文件系统函数可能会返回意外的结果 大于 2GB 的文件

    【讨论】:

    • 为什么它“更好”?它和我的版本几乎一样,除了它会为超过 2GB 的文件返回错误的大小(加上 OP 从不要求剩余的功率单位)。
    • @AlixAxel 更好,因为它只有一半大小并且仍然易于阅读。我也打赌它会更快。但是,嘿,这不是个人的。我自己没有想到。你的版本也很酷!赞成它;)
    • Adnan 发布了最冗长但也是最有效的答案。使用 log 函数来识别单位比使用简单的不等式要慢得多。即使在循环中使用连续的除法语句也比使用 log 快得多
    • @PiTheNumber 请注意filesize() doc 处的注释:“由于 PHP 的整数类型是有符号的,并且许多平台使用 32 位整数,因此对于大于 2GB 的文件,某些文件系统函数可能会返回意外结果”。由于这个以及更多的原因,我不太相信有人会使用 PHP 来操作文件,其大小以 TB 计算,更不用说更高的规模了。另外,我怀疑你的函数比 Alix Axel 更快,因为你使用的是 pow 函数,资源消耗与 Alix 使用的 log 相似。
    • 我没有说它更快什么的。只是它看起来更好。但只是为了好玩,我试图做一个基准测试,但我没有得到任何可用的结果。我不应该在键盘上运行它:codepad.org/o6cWsjIi
    【解决方案5】:

    我认为这是一种更好的方法。简单直接。

    public function sizeFilter( $bytes )
    {
        $label = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB' );
        for( $i = 0; $bytes >= 1024 && $i < ( count( $label ) -1 ); $bytes /= 1024, $i++ );
        return( round( $bytes, 2 ) . " " . $label[$i] );
    }
    

    【讨论】:

      【解决方案6】:

      这是基于@adnan 的出色回答。

      变化:

      • 添加了内部文件大小()调用
      • 回归早期风格
      • 在 1 个字节上保存一个连接

      您仍然可以从函数中提取 filesize() 调用,以获得纯字节格式化函数。但这适用于文件。


      /**
       * Formats filesize in human readable way.
       *
       * @param file $file
       * @return string Formatted Filesize, e.g. "113.24 MB".
       */
      function filesize_formatted($file)
      {
          $bytes = filesize($file);
      
          if ($bytes >= 1073741824) {
              return number_format($bytes / 1073741824, 2) . ' GB';
          } elseif ($bytes >= 1048576) {
              return number_format($bytes / 1048576, 2) . ' MB';
          } elseif ($bytes >= 1024) {
              return number_format($bytes / 1024, 2) . ' KB';
          } elseif ($bytes > 1) {
              return $bytes . ' bytes';
          } elseif ($bytes == 1) {
              return '1 byte';
          } else {
              return '0 bytes';
          }
      }
      

      【讨论】:

        【解决方案7】:

        这将是一个更简洁的实现:

        function size2Byte($size) {
            $units = array('KB', 'MB', 'GB', 'TB');
            $currUnit = '';
            while (count($units) > 0  &&  $size > 1024) {
                $currUnit = array_shift($units);
                $size /= 1024;
            }
            return ($size | 0) . $currUnit;
        }
        

        【讨论】:

          【解决方案8】:
          function calcSize($size,$accuracy=2) {
              $units = array('b','Kb','Mb','Gb');
              foreach($units as $n=>$u) {
                  $div = pow(1024,$n);
                  if($size > $div) $output = number_format($size/$div,$accuracy).$u;
              }
              return $output;
          }
          

          【讨论】:

            【解决方案9】:
            function getNiceFileSize($file, $digits = 2){
                if (is_file($file)) {
                    $filePath = $file;
                    if (!realpath($filePath)) {
                        $filePath = $_SERVER["DOCUMENT_ROOT"] . $filePath;
                    }
                    $fileSize = filesize($filePath);
                    $sizes = array("TB", "GB", "MB", "KB", "B");
                    $total = count($sizes);
                    while ($total-- && $fileSize > 1024) {
                        $fileSize /= 1024;
                    }
                    return round($fileSize, $digits) . " " . $sizes[$total];
                }
                return false;
            }
            

            【讨论】:

              【解决方案10】:
              //Get the size in bytes
              function calculateFileSize($size)
              {
                 $sizes = ['B', 'KB', 'MB', 'GB'];
                 $count=0;
                 if ($size < 1024) {
                  return $size . " " . $sizes[$count];
                  } else{
                   while ($size>1024){
                      $size=round($size/1024,2);
                      $count++;
                  }
                   return $size . " " . $sizes[$count];
                 }
              }
              

              【讨论】:

                【解决方案11】:

                问题的所有答案都使用 1 KB = 1024 字节,这是 错误的! (1 kibibyte = 1024 字节

                由于问题要求转换文件大小,它应该使用 1 KB = 1000 字节(参见 https://wiki.ubuntu.com/UnitsPolicy

                function format_bytes($bytes, $precision = 2) {
                    $units = array('B', 'KB', 'MB', 'GB');
                
                    $bytes = max($bytes, 0);
                    $pow = floor(($bytes ? log($bytes) : 0) / log(1000));
                    $pow = min($pow, count($units) - 1);
                
                    $bytes /= pow(1000, $pow);
                
                    return round($bytes, $precision) . ' ' . $units[$pow];
                }
                

                【讨论】:

                • 这个答案是唯一一个基于SI标准技术上正确的答案(除了KB应该是kB)如果你使用1024作为你的除数,那么单位应该表示为KiB,MiB,GiB, TiB等
                【解决方案12】:

                这是一个将 Bytes 转换为 KB、MB、GB、TB 的简单函数:

                # Size in Bytes
                $size = 14903511;
                # Call this function to convert bytes to KB/MB/GB/TB
                echo convertToReadableSize($size);
                # Output => 14.2 MB
                
                function convertToReadableSize($size){
                  $base = log($size) / log(1024);
                  $suffix = array("", "KB", "MB", "GB", "TB");
                  $f_base = floor($base);
                  return round(pow(1024, $base - floor($base)), 1) . $suffix[$f_base];
                }
                

                【讨论】:

                  猜你喜欢
                  • 2016-12-27
                  • 2023-02-13
                  • 2018-09-22
                  • 2014-08-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-08-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多