Hon*_*hař 24 php file-io x86 filesize large-files
我需要获得大小超过2 GB的文件的文件大小.(在4.6 GB文件上测试).没有外部程序有没有办法做到这一点?
当前状态:
filesize(),stat()并fseek()失败fread()和feof()工作通过读取文件内容可以获得文件大小(非常慢!).
$size = (float) 0;
$chunksize = 1024 * 1024;
while (!feof($fp)) {
fread($fp, $chunksize);
$size += (float) $chunksize;
}
return $size;
Run Code Online (Sandbox Code Playgroud)
我知道如何在64位平台上使用它(使用fseek($fp, 0, SEEK_END)和ftell()),但我需要32位平台的解决方案.
解决方案:我已经为此启动了开源项目.
Big File Tools是在PHP中操作超过2 GB的文件所需的hacks集合(即使在32位系统上).
Uns*_*ned 21
这是一种可能的方法:
它首先尝试使用适合平台的shell命令(Windows shell替换修饰符或*nix/Mac stat命令).如果失败,它会尝试COM(如果在Windows上),最后再回到filesize().
/*
* This software may be modified and distributed under the terms
* of the MIT license.
*/
function filesize64($file)
{
static $iswin;
if (!isset($iswin)) {
$iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
}
static $exec_works;
if (!isset($exec_works)) {
$exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC');
}
// try a shell command
if ($exec_works) {
$cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : "stat -c%s \"$file\"";
@exec($cmd, $output);
if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) {
return $size;
}
}
// try the Windows COM interface
if ($iswin && class_exists("COM")) {
try {
$fsobj = new COM('Scripting.FileSystemObject');
$f = $fsobj->GetFile( realpath($file) );
$size = $f->Size;
} catch (Exception $e) {
$size = null;
}
if (ctype_digit($size)) {
return $size;
}
}
// if all else fails
return filesize($file);
}
Run Code Online (Sandbox Code Playgroud)
我已经开始了名为Big File Tools的项目.它被证明适用于Linux,Mac和Windows(甚至是32位变体).即使对于大文件(> 4GB),它也能提供字节精确的结果.在内部,它使用砖/数学 - 任意精度算术库.
使用composer安装它.
composer install jkuchar/BigFileTools
Run Code Online (Sandbox Code Playgroud)
并使用它:
<?php
$file = BigFileTools\BigFileTools::createDefault()->getFile(__FILE__);
echo $file->getSize() . " bytes\n";
Run Code Online (Sandbox Code Playgroud)
结果是BigInteger,因此您可以使用结果进行计算
$sizeInBytes = $file->getSize();
$sizeInMegabytes = $sizeInBytes->toBigDecimal()->dividedBy(1024*1024, 2, \Brick\Math\RoundingMode::HALF_DOWN);
echo "Size is $sizeInMegabytes megabytes\n";
Run Code Online (Sandbox Code Playgroud)
Big File Tools内部使用驱动程序可靠地确定所有平台上的确切文件大小.以下是可用驱动程序列表(更新2016-02-05)
| Driver | Time (s) ? | Runtime requirements | Platform
| --------------- | ------------------- | -------------- | ---------
| CurlDriver | 0.00045299530029297 | CURL extension | -
| NativeSeekDriver | 0.00052094459533691 | - | -
| ComDriver | 0.0031449794769287 | COM+.NET extension | Windows only
| ExecDriver | 0.042937040328979 | exec() enabled | Windows, Linux, OS X
| NativeRead | 2.7670161724091 | - | -
Run Code Online (Sandbox Code Playgroud)
你可以使用BigFileTools中的任何一个或默认选择最快的(BigFileTools::createDefault())
use BigFileTools\BigFileTools;
use BigFileTools\Driver;
$bigFileTools = new BigFileTools(new Driver\CurlDriver());
Run Code Online (Sandbox Code Playgroud)