Один из вариантов - поиск до метки 2 ГБ, а затем чтение длины оттуда ...
function getTrueFileSize($filename) {
$size = filesize($filename);
if ($size === false) {
$fp = fopen($filename, 'r');
if (!$fp) {
return false;
}
$offset = PHP_INT_MAX - 1;
$size = (float) $offset;
if (!fseek($fp, $offset)) {
return false;
}
$chunksize = 8192;
while (!feof($fp)) {
$size += strlen(fread($fp, $chunksize));
}
} elseif ($size < 0) {
// Handle overflowed integer...
$size = sprintf("%u", $size);
}
return $size;
}
Таким образом, в основном это ищет наибольшее целое число с положительным знаком в PHP (2 ГБ длябитовая система), а затем выполняет чтение с использованием блоков по 8 КБ (что должно быть справедливым компромиссом для лучшей эффективности памяти по сравнению с эффективностью передачи диска).
Также обратите внимание, что я не добавляю $chunksize
к размеру.Причина в том, что fread
может фактически возвращать больше или меньше байтов, чем $chunksize
, в зависимости от ряда возможностей.Поэтому вместо этого используйте strlen
, чтобы определить длину проанализированной строки.