php 操作文件大小辅助类
程序员文章站
2022-05-07 08:28:28
...
这个类可以判断文件的大小,即使大于2GB,它可以使用不同的方法来确定一个大的文件。
<?php require ("filesizeHelper.php"); $filesizeHelper = new FilesizeHelper(); $file = 'F:codepearl.text'; //$file ="/media/disk-1/Just.A.Very.Large.File.avi"; $filesize = $filesizeHelper->getFileSize($file); echo"<pre>"; var_dump($filesize);
<?php /** * ---------------------------------------------------------------------- * FileSizeHelper * ---------------------------------------------------------------------- * * Class for manipulating large files (bigger than 2GB) * * This class detects the real file size of a specified file even if the * file size is begger than 2GB, the class also able to format the resulted * file size in KB, MB, GB, TB units which make it more readable. * * The class uses several methods to detect bigger file sizes: * 1. The native filesize() function * 2. Using the cURL module * 3. Using the php native seek function * 4. Windows COM interface (on windows server) * 5. Using external program (exec() function needed) */ class FilesizeHelper { /** * File path * * @var string * @accessprivate */ private $path; /** * File size in bytes * * @var float * @accessprivate */ private $byteSize; /** * Whether we are on Windows platform or another OS (*nix and MacOS) * * @var bool * @accessprivate */ private $isWindows; /** * Constructor * * @accesspublic * @param void * @return void */ public function __construct() { // Check if we are on Windows platform $this->isWindows = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'); } /** * Gets the size of the specified file * * @accesspublic * @paramstringThe file path * @paramboolWhether to format the file size in KB, MB, GB, TB * @return mixed */ public function getFileSize($file, $formatted = true) { // Set the path of the file $this->path = $file; // Check for a valid file path $this->__checkFilePath(); // Get the file size in bytes $this->byteSize = (float) $this->__getByteSize(); // If failed to get the file size or the file size is zero, return a blank result if (!$this->byteSize) { if (!$formatted) { return 0; } // Return a blank array $blank_size = $this->__formatFileSize(); return array(0, $blank_size[0], $blank_size[1]); } // Return the bytesize if no formatting is needed if (!$formatted) { return $this->byteSize; } // Return an array containing the file size information return $this->__formatFileSize(); } /** * Formats the file size in KB, MB, GB, TB units * * @accessprivate * @param void * @return arrayReturn arry containing the file size information */ private function __formatFileSize() { // If the file size is zero return a blank result $_size = $this->byteSize; if (!$_size || $_size < 0) { return array(0, '0 B', array(0, 'B')); } // If the file size is smaller than 1KB if ($_size <= 1024) { return array(0, '1 KB', array(1, 'KB')); } // Set an array of all file size units $size_units = Array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'); // Set the initial unit to Bytes $unit = $size_units[0]; // Loop through all file size units for ($i = 1; ($i < count($size_units) && $_size >= 1024); $i++) { $_size = $_size / 1024; $unit = $size_units[$i]; } // Set the number of digits after the decimal place in the resulted file size $round = 2; // If the file size is in KiloByte we do not need any decimal numbers if ($unit == 'KB') { $round = 0; } // Round the file size $formatted = round((float) $_size, $round); // Return the file size data return array($this->byteSize, $formatted ."". $unit, array($formatted, $unit)); } /** * Chek if the file is exist * * @accessprivate * @param void * @return void */ private function __checkFilePath() { clearstatcache(); if (!file_exists($this->path)) { throw new Exception("File not found at $this->path"); } } /** * Gets the size of the specified file in bytes * * @accessprivate * @param void * @return stringThe file size in bytes */ private function __getByteSize() { // Try the php native filesize() function. $bytesize = @filesize($this->path); if (false !== $bytesize && $bytesize >= 0) { return $bytesize; } // If filesize() fails with larger files, try to get the size using curl module. $bytesize = $this->__useCurl(); if ($bytesize) { return $bytesize; } // If curl fails to get the file size try using the php native seek function. $bytesize = $this->__useNativeSeek(); if ($bytesize) { return $bytesize; } // If the native seek fails to get the file size and we are on windows try using Windows COM interface $bytesize = $this->__useCom(); if ($bytesize) { return $bytesize; } // If all the above methods failed to get the file size try using external program (exec() function needed) $bytesize = $this->__useExec(); if ($bytesize) { return $bytesize; } // Unable to get the file size in bytes throw new Exception("Unable to get the file size for the file". $this->path ."!"); } /** * Gets the file size using curl module * * @accessprivate * @param void * @returnmixedThe file size as string or false when fail or cUrl module not available * @seehttp://www.php.net/manual/en/function.filesize.php#100434 */ private function __useCurl() { // If the curl module is not available return false if (!function_exists("curl_init")) { return false; } $ch = curl_init("file://". $this->path); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); $data = curl_exec($ch); curl_close($ch); if ($data !== false && preg_match('/Content-Length: (d+)/', $data, $matches)) { return (string) $matches[1]; } } /** * Gets the file size by using native fseek function * * @accessprivate * @param void * @returnmixedThe file size as string or false when fail * @seehttp://www.php.net/manual/en/function.filesize.php#79023 * @seehttp://www.php.net/manual/en/function.filesize.php#102135 */ private function __useNativeSeek() { // This should work for large files on 64bit platforms and for small files every where $fp = @fopen($this->path,"rb"); // If failed to open the file return false if (!$fp) { return false; } flock($fp, LOCK_SH); // Seeks past the end-of-file $res = fseek($fp, 0, SEEK_END); if ($res === 0) { // Get the current position of the file pointer $pos = ftell($fp); flock($fp, LOCK_UN); fclose($fp); // $pos will be positive int if file is <2GB // if is >2GB <4GB it will be negative number if ($pos >= 0) { return (string) $pos; } else { return sprintf("%u", $pos); } } else { flock($fp, LOCK_UN); fclose($fp); return false; } } /** * Gets the file size by using Windows COM interface * * @accessprivate * @param void * @returnmixedThe file size as string or false when fail or COM not available */ private function __useCom() { if (!$this->isWindows || !class_exists("COM")) { return false; } // Use the Windows COM interface $fsobj = new COM('Scripting.FileSystemObject'); if (dirname($this->path) == '.') { $this->path = ((substr(getcwd(), -1) == DIRECTORY_SEPARATOR) ? getcwd() . basename($this->path) : getcwd() . DIRECTORY_SEPARATOR . basename($this->path)); } // Get the file data $f = $fsobj->GetFile($this->path); // Convert to string return (string) $f->Size; } /** * Gets the file size by using external program (exec needed) * * @accessprivate * @param void * @return mixedThe file size as string or false when fail or or exec is disabled */ private function __useExec() { // If exeec is disable return false if (!function_exists("exec")) { return false; } //Escape the file path string to be used as a shell argument $escapedPath = escapeshellarg($this->path); // If we are on Windows if ($this->isWindows) { // Try using the NT substition modifier %~z $size = trim(exec("for %F in ($escapedPath) do @echo %~zF")); } // If other OS (*nix and MacOS) else { // If the platform is not Windows, use the stat command (should work for *nix and MacOS) $size = trim(exec("stat -c%s $escapedPath")); } // If the return is not blank, not zero, and is number if ($size && ctype_digit($size)) { return (string) $size; } // An error has occured return false; } }