Лучший способ получить размер файла, который больше, чем 2 ГБ в php? - PullRequest
2 голосов
/ 04 марта 2011

Я хочу проверить размер файла локальных дисков на windows OS. Но встроенная функция PHP filesize() работает только тогда, когда размер файла меньше 2GB. Файл, значение которого больше 2GB, вернет неправильный номер. Так что есть другой способ получить размер файла, который больше 2GB?

Большое спасибо !!

Ответы [ 7 ]

4 голосов
/ 04 марта 2011

Вы всегда можете использовать метод размера файла системы.

Для Windows: Команда Windows только для размера файла?

@ echo off

эхо% ~ z1

Для Linux

stat -c %s filenam

Вы могли бы запустить их с помощью команды exec php.

1 голос
/ 08 февраля 2019

PHP функция для получения размера файла локального файла с незначительным использованием памяти:

function get_file_size ($file) {
   $fp = @fopen($file, "r");
   @fseek($fp,0,SEEK_END);
   $filesize = @ftell($fp);
   fclose($fp);
   return $filesize;
}

В первой строке кода $file открывается в режиме только для чтения и присоединяется к $fp handle.
Во второй строке указатель перемещается с помощью fseek () в конец $file.
Наконец, ftell () возвращает позицию байтауказателя в $file, который теперь является его концом.
Функция fopen () бинарно-безопасна и подходит для использования даже с очень большими файлами.
Вышекод тоже очень быстрый.

1 голос
/ 04 марта 2011

эта функция работает для любого размера:

function fsize($file) {
  // filesize will only return the lower 32 bits of
  // the file's size! Make it unsigned.
  $fmod = filesize($file);
  if ($fmod < 0) $fmod += 2.0 * (PHP_INT_MAX + 1);

  // find the upper 32 bits
  $i = 0;

  $myfile = fopen($file, "r");

  // feof has undefined behaviour for big files.
  // after we hit the eof with fseek,
  // fread may not be able to detect the eof,
  // but it also can't read bytes, so use it as an
  // indicator.
  while (strlen(fread($myfile, 1)) === 1) {
    fseek($myfile, PHP_INT_MAX, SEEK_CUR);
    $i++;
  }

  fclose($myfile);

  // $i is a multiplier for PHP_INT_MAX byte blocks.
  // return to the last multiple of 4, as filesize has modulo of 4 GB (lower 32 bits)
  if ($i % 2 == 1) $i--;

  // add the lower 32 bit to our PHP_INT_MAX multiplier
  return ((float)($i) * (PHP_INT_MAX + 1)) + $fmod;
}

примечание: эта функция может быть немного медленной для файлов> 2 ГБ

(взято из комментариев php)

0 голосов
/ 07 февраля 2017

Чтобы ответить на ответ Джошендо , если вы работаете в Unix-подобной ОС (Linux, OSX, macOS и т. Д.), Вы можете немного обмануть, используя ls:

$fileSize = trim(shell_exec("ls -nl " . escapeshellarg($fullPathToFile) . " | awk '{print $5}'"));

trim() есть, чтобы удалить возврат каретки в конце. Остается строка, содержащая полный размер файла на диске, независимо от размера или состояния кэша статистики, без человеческого форматирования, такого как запятые.

Просто будьте осторожны, откуда поступают данные в $fullPathToFile ... при выполнении системных вызовов вы не хотите доверять предоставленным пользователем данным. escapeshellarg , вероятно, защитит вас, но лучше, чем потом сожалеть.

0 голосов
/ 25 июля 2013

Эта функция возвращает размер для файлов> 2 ГБ и довольно быстрая.

function file_get_size($file) {
    //open file
    $fh = fopen($file, "r"); 
    //declare some variables
    $size = "0";
    $char = "";
    //set file pointer to 0; I'm a little bit paranoid, you can remove this
    fseek($fh, 0, SEEK_SET);
    //set multiplicator to zero
    $count = 0;
    while (true) {
        //jump 1 MB forward in file
        fseek($fh, 1048576, SEEK_CUR);
        //check if we actually left the file
        if (($char = fgetc($fh)) !== false) {
            //if not, go on
            $count ++;
        } else {
            //else jump back where we were before leaving and exit loop
            fseek($fh, -1048576, SEEK_CUR);
            break;
        }
    }
    //we could make $count jumps, so the file is at least $count * 1.000001 MB large
    //1048577 because we jump 1 MB and fgetc goes 1 B forward too
    $size = bcmul("1048577", $count);
    //now count the last few bytes; they're always less than 1048576 so it's quite fast
    $fine = 0;
    while(false !== ($char = fgetc($fh))) {
        $fine ++;
    }
    //and add them
    $size = bcadd($size, $fine);
    fclose($fh);
    return $size;
}
0 голосов
/ 04 марта 2011
<?php
$files = `find / -type f -size +2097152`;
?>
0 голосов
/ 04 марта 2011

Если вы используете сервер Linux, используйте системную команду.

$last_line = system('ls');

Это пример того, как он используется. Если вы замените «ls» на:

du <filename>

тогда он вернет целое число размера файла в переменной $ last_line. Например:

472    myProgram.exe

означает, что это 472 КБ. Вы можете использовать регулярные выражения, чтобы получить только число. Я не так часто использовал команду du, поэтому вы захотите поиграть с ней и посмотреть, что выводится для файлов> 2 ГБ.

http://php.net/manual/en/function.system.php

...