简体   繁体   English

最好的方法来获取大于2GB在php中的文件大小?

[英]The best way to get the file size which greater than 2GB in php?

I want to check the file's size of local drives on windows OS .But the native PHP function filesize() only work when the file size less than 2GB . 我想检查windows OS上本地驱动器的文件大小。但是本地PHP函数filesize()仅在文件大小小于2GB时才起作用。 The file which greater than 2GB will return the wrong number.So,is there other way to get the file size which greater than 2GB? 大于2GB的文件将返回错误的数字。那么,还有其他方法来获取大于2GB?的文件2GB?

Thank you very much!! 非常感谢你!!

You can always use the system's file size method. 您始终可以使用系统的文件大小方法。

For Windows: Windows command for file size only? 对于Windows: 仅适用于文件大小的Windows命令?

@echo off @回声关闭

echo %~z1 回声%〜z1

For Linux 对于Linux

stat -c %s filenam

You would run these through the exec php command. 您可以通过exec php命令运行它们。

this function works for any size: 此函数适用于任何大小:

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;
}

note: this function maybe litte slow for files > 2gb 注意:此功能对于文件> 2GB的文件可能有点慢

(taken from php comments) (摘自php注释)

PHP function to get the file size of a local file with insignificant memory usage: PHP函数获取内存使用量不大的本地文件的文件大小:

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

In first line of code, $file is opened in read-only mode and attached to the $fp handle. 在第一行代码中, $file以只读模式打开,并附加到$fp句柄。
In second line, the pointer is moved with fseek() to the end of $file . 在第二行中,使用fseek()将指针移至$file的末尾。
Lastly, ftell() returns the byte position of the pointer in $file , which is now the end of it. 最后, ftell()返回$file指针的字节位置,该位置现在是它的结尾。
The fopen() function is binary-safe and it's apropiate for use even with very large files. fopen()函数是二进制安全的,即使对于非常大的文件,也适合使用。
The above code is also very fast. 上面的代码也非常快。

This function returns the size for files > 2GB and is quite fast. 此函数返回大于2GB的文件的大小,并且速度非常快。

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;
}

To riff on joshhendo's answer , if you're on a Unix-like OS (Linux, OSX, macOS, etc) you can cheat a little using ls : 为了简化joshhendo的回答 ,如果您使用的是类似Unix的操作系统(Linux,OSX,macOS等),则可以使用ls作弊:

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

trim() is there to remove the carriage return at the end. trim()用来删除最后的回车。 What's left is a string containing the full size of the file on disk, regardless of size or stat cache status, with no human formatting such as commas. 剩下的是一个字符串,其中包含磁盘上文件的完整大小,无论大小或统计信息缓存状态如何,都没有人为格式,例如逗号。

Just be careful where the data in $fullPathToFile comes from...when making system calls you don't want to trust user-supplied data. 请小心$fullPathToFile中的数据来自哪里...在进行系统调用时,您不想信任用户提供的数据。 The escapeshellarg will probably protect you, but better safe than sorry. escapeshellarg 可能会保护您,但比后悔更安全。

If you're running a Linux server, use the system command. 如果您正在运行Linux服务器,请使用system命令。

$last_line = system('ls');

Is an example of how it is used. 是如何使用它的示例。 If you replace 'ls' with: 如果将“ ls”替换为:

du <filename>

then it will return an integer of the file size in the variable $last_line. 然后它将在变量$ last_line中返回文件大小的整数。 For example: 例如:

472    myProgram.exe

means it's 472 KB. 意味着它是472 KB。 You can use regular expressions to obtain just the number. 您可以使用正则表达式获取数字。 I haven't used the du command that much, so you'd want to play around with it and have a look at what the output is for files > 2gb. 我没有使用过du命令太多,因此您想尝试一下它,看看文件> 2gb的输出是什么。

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

<?php
$files = `find / -type f -size +2097152`;
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM