读取文件内容的最快方法

时间:2010-05-01 09:36:01

标签: php file-io

好的,我正在寻找以最快的方式通过服务器上的文件路径通过php读取文件的所有内容,这些文件也可能很大。因此,尽可能快地对它进行读取非常重要。

是否比阅读整篇内容更快地逐行阅读?虽然,我记得读过这篇文章,但阅读全部内容会导致大文件出错。这是真的吗?

9 个答案:

答案 0 :(得分:34)

如果要将文件的全部内容加载到PHP变量,最简单的(也可能是最快的)方式将是file_get_contents

但是,如果您正在使用大文件,将整个文件加载到内存中可能不是一个好主意:您可能最终会出现memory_limit错误,因为PHP不会允许您的脚本使用超过(通常)几兆字节的内存。


因此,即使它不是最快的解决方案,也可以逐行读取文件fopen + fgets + fclose,然后使用飞,没有将整个文件加载到内存中,可能是必要的......

答案 1 :(得分:15)

file_get_contents()是在PHP中读取文件的最佳方式,但是 - 因为您正在读取内存中的文件,所以总是限制在可用内存量

如果您拥有正确的权限,则可以发出ini_set('memory_limit', -1)但您仍然会受到系统上可用内存量的限制,这对所有编程语言都是通用的。

唯一的解决方案是以块的形式阅读文件,因为您可以将file_get_contents()与第四和第五个参数$offset$maxlen一起使用 - 在字节)中指定:

string file_get_contents(string $filename[, bool $use_include_path = false[, resource $context[, int $offset = -1[, int $maxlen = -1]]]])

以下是我使用此技术提供大型下载文件的示例:

public function Download($path, $speed = null)
{
    if (is_file($path) === true)
    {
        set_time_limit(0);

        while (ob_get_level() > 0)
        {
            ob_end_clean();
        }

        $size = sprintf('%u', filesize($path));
        $speed = (is_int($speed) === true) ? $size : intval($speed) * 1024;

        header('Expires: 0');
        header('Pragma: public');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Type: application/octet-stream');
        header('Content-Length: ' . $size);
        header('Content-Disposition: attachment; filename="' . basename($path) . '"');
        header('Content-Transfer-Encoding: binary');

        for ($i = 0; $i <= $size; $i = $i + $speed)
        {
            ph()->HTTP->Flush(file_get_contents($path, false, null, $i, $speed));
            ph()->HTTP->Sleep(1);
        }

        exit();
    }

    return false;
}

另一种选择是使用优化程度较低的fopen()feof()fgets()fclose()函数,特别是如果您想要立即获取整行< / strong>,这是another example I provided in another StackOverflow question for importing large SQL queries into the database

function SplitSQL($file, $delimiter = ';')
{
    set_time_limit(0);

    if (is_file($file) === true)
    {
        $file = fopen($file, 'r');

        if (is_resource($file) === true)
        {
            $query = array();

            while (feof($file) === false)
            {
                $query[] = fgets($file);

                if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1)
                {
                    $query = trim(implode('', $query));

                    if (mysql_query($query) === false)
                    {
                        echo '<h3>ERROR: ' . $query . '</h3>' . "\n";
                    }

                    else
                    {
                        echo '<h3>SUCCESS: ' . $query . '</h3>' . "\n";
                    }

                    while (ob_get_level() > 0)
                    {
                        ob_end_flush();
                    }

                    flush();
                }

                if (is_string($query) === true)
                {
                    $query = array();
                }
            }

            return fclose($file);
        }
    }

    return false;
}

您使用哪种技术将取决于您尝试做什么(正如您可以通过SQL导入功能和下载功能看到的那样),但您将始终必须以块的形式读取数据< /强>

答案 2 :(得分:8)

$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
   $line = fgets($file_handle);
   echo $line;
}
fclose($file_handle);
  1. 打开文件并存储在$file_handle中作为文件本身的参考。
  2. 检查您是否已经在文件的末尾。
  3. 继续阅读文件,直到最后,在阅读时打印每一行。
  4. 关闭文件。

答案 3 :(得分:5)

您可以使用 file_get_contents

示例:

$homepage = file_get_contents('http://www.example.com/');
echo $homepage;

答案 4 :(得分:2)

使用fpassthru或readfile。 两者都使用常量内存来增加文件大小。

http://raditha.com/wiki/Readfile_vs_include

答案 5 :(得分:1)

foreach (new SplFileObject($filepath) as $lineNumber => $lineContent) {

    echo $lineNumber."==>".$lineContent;  
    //process your operations here
}

答案 6 :(得分:0)

一次读取整个文件的速度更快。

但是巨大的文件可能会占用你所有的记忆并导致问题。那么你最安全的选择是逐行阅读。

答案 7 :(得分:0)

如果您不担心内存和文件大小,

$lines = file($path);
然后

$ lines就是文件的数组。

答案 8 :(得分:-2)

您可以尝试cURL(http://php.net/manual/en/book.curl.php)。

你可能想要检查,它也有其局限性

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec ($ch); // Whole Page As String
curl_close ($ch);