2

为了更清楚地说明这一点,我将放置代码示例:

$file = fopen('filename.ext', 'rb');

// Assume $pos has been declared
// method 1
fseek($file, $pos);
$parsed = fread($file, 2);

// method 2
while (!feof($file)) {
    $data = fread($file, 1000000);
}

$data = bin2hex($data);
$parsed = substr($data, $pos, 2);

$fclose($file);

方法 1 中大约有 40 个 fread()(可能有 15 个 fseek()),而方法 2 中有 1 个 fread()。我唯一想知道的是,当您实际上只提取 100 个字节时,加载 1000000 个字节是否过大总字节数(在文件中间都相对靠近)。

那么哪个代码会执行得更好呢?使用哪个代码更有意义?一个快速的解释将不胜感激。

4

3 回答 3

4

如果您已经知道要查找的偏移量,那么 fseek 是最好的方法,因为如果您只需要几个字节,就没有理由将整个文件加载到内存中。第一种方法更好,因为您直接跳到文件流中您想要的内容并读出一小部分。第二种方法要求您将整个文件读入内存,然后在您可以直接从文件中读取的情况下进行查找。希望这能回答你的问题

于 2010-03-02T15:52:30.963 回答
3

文件以簇为单位读取,一个簇通常为 8 kb 左右。通常会提前读取几个簇。

因此,如果文件只有几 kb,与读取整个文件相比,使用 fseek 几乎没有什么好处。文件系统无论如何都会读取整个文件。

如果文件相当大,如您的情况,则只需读取少数集群,因此第一种方法应该执行得更好。在最坏的情况下,仍然会从磁盘读取所有数据,但您的应用程序仍将使用更少的内存。

于 2010-03-02T15:56:07.163 回答
1

似乎寻找你想要的位置然后只读取你需要的字节是最好的方法。

正确的答案是(一如既往)真实地测试它而不是猜测。在您的服务器环境中运行您的两个示例并进行一些时间测量。还要检查内存使用情况。一旦你有一些硬数据来备份它,就可以进行优化。

于 2010-03-02T16:05:01.233 回答