Лучше ли использовать fseek() fread() для отдельных строк или fread() для всего файла и substr для анализа?


Чтобы сделать это более понятным, я приведу примеры кода:

$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()) против 1 fread() в методе 2. Единственное, что мне интересно, так это то, что загрузка в 1000000 байт является излишней, когда вы действительно извлекаете всего, может быть, 100 байт (все относительно близко друг к другу в середине файла).

Итак, какой код будет работать лучше? Какой код имеет больше смысла использовать? Краткое объяснение было бы очень полезно оцененный.

Author: wambotron, 2010-03-02

3 answers

Если вы уже знаете, какое смещение ищете, fseek - лучший метод здесь, так как нет причин загружать весь файл в память, если вам нужно всего несколько байтов. Первый способ лучше, потому что вы сразу переходите к тому, что вам нужно в потоке файлов, и считываете небольшую часть. Второй метод требует, чтобы вы прочитали весь файл в память, а затем просмотрели его, в то время как вы могли бы просто прочитать его прямо из файла. Надеюсь, это ответ на ваш вопрос

 4
Author: robmerica, 2010-03-02 15:52:30

Файлы считываются в единицах кластеров, а кластер обычно составляет около 8 кб. Обычно несколько кластеров считываются заранее.

Таким образом, если размер файла составляет всего несколько кб, использование fseek дает очень мало преимуществ по сравнению с чтением всего файла. Файловая система в любом случае прочитает весь файл целиком.

Если файл значительно больше, как в вашем случае, необходимо прочитать только несколько кластеров, поэтому первый метод должен работать лучше. В худшем случае все данные все равно будут считывайте с диска, но ваше приложение все равно будет использовать меньше памяти.

 3
Author: Guffa, 2010-03-02 20:08:05

Похоже, что поиск нужной позиции, а затем чтение только тех байтов, которые вам нужны, - это лучший подход.

Но правильный ответ (как всегда) заключается в том, чтобы проверить его на практике, а не угадывать. Запустите два примера в своей серверной среде и проведите некоторые измерения времени. Также проверьте использование памяти. Затем произведите оптимизацию, как только у вас появятся надежные данные для ее резервного копирования.

 1
Author: Martin Wickman, 2010-03-02 16:05:01