PHP filesize()On Files> 2 GB

问题描述 投票:5回答:6

我一直在努力研究如何在PHP中获得> = 2 GB的文件的有效文件大小。

例 在这里,我使用filesize()函数检查大小为3,827,394,560字节的文件的文件大小:

echo "The file is " . filesize('C:\MyFile.rar') . " bytes.";

结果 这是它返回的内容:

该文件是-467572736字节。

背景 PHP使用有符号整数,这意味着它可以表示的最大数字是2,147,483,647(+/- 2 GB)。 这是有限的地方。

php filesize signed
6个回答
4
投票

http://us.php.net/manual/en/function.filesize.php#102135提供了一种完整而正确的方法,可以在PHP中查找大于2GB的文件大小,而不依赖于特定于操作系统的接口。

它的要点是你首先使用filesize获得“低”位,然后打开+搜索文件以确定它包含多少2GB的倍数(“高”位)。


3
投票

我试过并且显然有效的解决方案是使用COM FileObject的“Size”属性。我不完全确定它使用的是什么类型。

这是我的代码:

function real_filesize($file_path)
{
    $fs = new COM("Scripting.FileSystemObject");
    return $fs->GetFile($file_path)->Size;
}

它简称如下:

$file = 'C:\MyFile.rar';
$size = real_filesize($file);
echo "The size of the file is: $size";

结果

文件大小为:3,827,394,560字节


1
投票

我正在使用不同的方法,节省宝贵的服务器资源,看看我的GitHub存储库github.com/eladkarako/download.eladkarako.com

它是一个简单,完整的下载仪表板,使用客户端头部请求克服了(*罕见)filesize错误的情况,授予它,它不会嵌入到页面的HTML源代码中,而是呈现(*修复)一段时间后,所以它更适合嗯...,让我们说,放松的场景..

要使此解决方案可用,应添加Apache .htaccess(或PHP中的标头),允许客户端使用Content-Length值。

基本上你可以减少.htaccess只允许Content-Length删除其他CORS规则..使网站更安全。

没有使用jQuery,整个东西都写在我的三星文本编辑器中,并通过FTP从我的智能手机上传,在我的MILUIM..乘坐1.5小时的火车,但仍然无可挑剔;)


0
投票

我有一个“hacky”解决方案,效果很好。

请看THIS function我是如何做到的,你还需要包括this class功能可以很好地工作或根据你的需要改变。

例:

include_once 'class.os.php';
include_once 'function.filesize.32bit.php';

// Must be real path to file
$file = "/home/username/some-folder/yourfile.zip";
echo get_filesize($file);

此功能不是理想的解决方案,但这是如何工作:

  1. 首先检查shell_exec是否已启用PHP。如果启用,它将通过shell命令检查real filesize。
  2. 如果shell失败并且OS是64位将返回正常的filesize()信息
  3. 如果是32位将进入“分块”方法并计算文件大小读取字节。

注意!

读取之后保持字符串格式的结果可以很容易地计算,因为PHP可以计算字符串,但如果将结果超过2GB转换为整数,则会遇到与以前相同的问题。

警告!

Chunking非常慢,如果你想循环它,你将有内存泄漏或脚本可能需要几分钟才能完成所有文件的读取。如果您在启用了shell_exec的服务器上使用此功能,您将获得超快速读取。

附:

如果你对这里的变化有所了解,那么改进的人可以随意提交。


0
投票

我知道这是一个老人,但我正在使用PHP x64 5.5.38(现在)并且不想升级到最新的7.x版本。

我确实阅读了所有关于查找大于2GB的文件大小的帖子,但所有解决方案对于大量文件都非常慢。

所以,昨天我创建了C / C ++ PHP扩展“php_filesize.dll”,它利用C / C ++的强大功能通过我发现的几种方法查找文件大小,它也兼容UTF-8并且速度非常快。

你可以尝试一下:http://www.jobnik.org/files/PHP/php_filesize.zip

用法:

方法:

0 - 使用GetFileAttributesEx

1 - 使用CreateFile

2 - 使用FindFirstFile

-1 - 使用stat64(默认和可选)

$ fsize = php_filesize(“filepath”,$ method_optional);

  • 以字符串形式返回最多9个PetaByte的文件大小

积分:

FileSize方法:Check filesize without opening file in c++?

UTF-8支持:https://github.com/kenjiuno/php-wfio


0
投票

对于碰巧在linux主机上的人来说,我找到的最简单的解决方案是使用:

exec("stat --format=\"%s\" \"$file\"");

假设文件名中没有引号或换行符,并且技术上返回一个字符串而不是我想的数字,但它适用于此方法以获得human readable file size

我测试过的最大文件大约是3.6 GB。


-1
投票

为了获得正确的文件大小,我经常使用几个月前我自己编写的这段代码。我的代码使用:exec / com / stat。我知道它的极限,但这是一个很好的起点。最好的想法是在64位架构上使用filesize()

<?php
  ######################################################################
  # Human size for files smaller or bigger than 2 GB on 32 bit Systems #
  # size.php - 1.3 - 21.09.2015 - Alessandro Marinuzzi - www.alecos.it #
  ######################################################################
  function showsize($file) {
    if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
      if (class_exists("COM")) {
        $fsobj = new COM('Scripting.FileSystemObject');
        $f = $fsobj->GetFile(realpath($file));
        $size = $f->Size;
      } else {
        $size = trim(@exec("for %F in (\"" . $file . "\") do @echo %~zF"));
      }
    } elseif (PHP_OS == 'Darwin') {
      $size = trim(@exec("stat -f %z " . $file));
    } else {
      $size = trim(@exec("stat -c %s " . $file));
    }
    if ((!is_numeric($size)) || ($size < 0)) {
      $size = filesize($file);
    }
    if ($size < 1024) {
      echo $size . ' Byte';
    } elseif ($size < 1048576) {
      echo number_format(round($size / 1024, 2), 2) . ' KB';
    } elseif ($size < 1073741824) {
      echo number_format(round($size / 1048576, 2), 2) . ' MB';
    } elseif ($size < 1099511627776) {
      echo number_format(round($size / 1073741824, 2), 2) . ' GB';
    } elseif ($size < 1125899906842624) {
      echo number_format(round($size / 1099511627776, 2), 2) . ' TB';
    } elseif ($size < 1152921504606846976) {
      echo number_format(round($size / 1125899906842624, 2), 2) . ' PB';
    } elseif ($size < 1180591620717411303424) {
      echo number_format(round($size / 1152921504606846976, 2), 2) . ' EB';
    } elseif ($size < 1208925819614629174706176) {
      echo number_format(round($size / 1180591620717411303424, 2), 2) . ' ZB';
    } else {
      echo number_format(round($size / 1208925819614629174706176, 2), 2) . ' YB';
    }
  }
?>

<?php include("php/size.php"); ?>

<?php showsize("files/VeryBigFile.tar"); ?>

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.