Gzeof: примеры (PHP)

PHP функция gzeof: примеры проверки конца сжатого файла
Раздел: Сжатие
gzeof(resource $stream): bool
Функция gzeof в PHP

Функция gzeof() проверяет, достигнут ли конец файла (End-Of-File, EOF) при чтении сжатого gz-файла, открытого с помощью gzopen(). Она используется во время последовательного чтения файлов в формате gzip (.gz) для определения момента завершения чтения данных.

Функция принимает один аргумент:

  • $stream (ресурс) - указатель на gz-файл, который должен быть корректно открыт функцией gzopen(). Этот ресурс становится недействительным после закрытия файла с помощью gzclose().

Возвращаемое значение: true, если указатель находится в конце файла или произошла ошибка (например, передан некорректный ресурс). В противном случае возвращается false.

Простые примеры использования
Пример 1: Базовое чтение файла
<?php
$gzfile = gzopen('example.txt.gz', 'r');
if ($gzfile) {
    while (!gzeof($gzfile)) {
        echo gzread($gzfile, 1024);
    }
    gzclose($gzfile);
}
?>
(Содержимое распакованного файла example.txt.gz)
Пример 2: Чтение по одной строке
<?php
$gzfile = gzopen('log.txt.gz', 'r');
$lineNumber = 0;
while (!gzeof($gzfile)) {
    $line = gzgets($gzfile);
    $lineNumber++;
    echo "Строка {$lineNumber}: {$line}";
}
gzclose($gzfile);
?>
Строка 1: Первая запись в логе
Строка 2: Вторая запись
...
Похожие функции в PHP

Для работы со сжатыми файлами в PHP существует ряд функций:

  • feof() - проверяет конец файла для обычных (несжатых) файлов. Используется с ресурсами, полученными через fopen().
  • gzread(), gzgets(), gzgetc() - функции для чтения данных из gz-файлов, которые обычно используются в паре с gzeof() в цикле.
  • gzinflate(), gzuncompress(), gzdecode() - функции для работы со сжатыми строками или данными в памяти, а не с файлами в файловой системе.

Функцию gzeof() предпочтительно использовать при последовательном чтении больших сжатых файлов, когда требуется прочитать файл от начала до конца, не загружая его полностью в память.

Альтернативы в других языках

Gzeof в Python

В Python для работы с gz-файлами используется модуль gzip. Аналогом цикла с проверкой конца файла является итерация по объекту файла.

import gzip
with gzip.open('example.txt.gz', 'rt') as f:
    for line in f:
        print(line, end='')
(Содержимое распакованного файла)
JavaScript (Node.js)

В Node.js для работы со сжатыми файлами используется модуль zlib вместе с потоками (streams). Проверка конца файла неявная, через события потока.

const zlib = require('zlib');
const fs = require('fs');
const gunzip = zlib.createGunzip();
const input = fs.createReadStream('example.txt.gz');
const output = fs.createWriteStream('example.txt');
input.pipe(gunzip).pipe(output);

Gzeof в MySQL

В MySQL нет прямой аналогии, так как это СУБД. Однако поддерживается сжатие данных на уровне протокола или таблиц (например, InnoDB page compression). Проверка конца потока данных осуществляется драйверами или клиентскими библиотеками.

Типичные ошибки
Ошибка 1: Передача некорректного ресурса
<?php
$result = gzeof('not_a_resource');
var_dump($result);
?>
Warning: gzeof() expects parameter 1 to be resource, string given
bool(false)
Ошибка 2: Проверка закрытого ресурса
<?php
$gzfile = gzopen('test.gz', 'r');
gzclose($gzfile);
if (gzeof($gzfile)) { // Ресурс уже закрыт
    echo "Конец файла";
}
?>
Warning: gzeof(): supplied resource is not a valid stream resource
Ошибка 3: Использование с неподдерживаемым режимом
<?php
// Открытие файла для записи
$gzfile = gzopen('output.gz', 'w');
if (gzeof($gzfile)) { // Для файла, открытого на запись, проверка EOF бессмысленна
    echo "Это сообщение вряд ли появится";
}
gzclose($gzfile);
?>
(Функция вернет false, так как для потока записи понятие "конец файла" неприменимо в момент открытия)
Изменения в последних версиях PHP

Функция gzeof() остается стабильной и не претерпела значительных изменений в последних основных версиях PHP 8.x. Поведение и сигнатура функции сохранились.

Важное изменение, касающееся всей работы с файлами в PHP 8: тип ошибки при передаче некорректного аргумента был изменен с предупреждения (E_WARNING) на исключение типа TypeError, если передается аргумент неподдерживаемого типа. Однако для gzeof(), которая ожидает ресурс, это изменение маловероятно, так как ресурсы являются отдельным типом.

Расширенные примеры
Пример 1: Обработка бинарного gz-файла с проверкой контрольной суммы
Пример php
<?php
function readGzFileWithCheck($filename) {
    $handle = gzopen($filename, 'rb'); // Бинарный режим
    if (!$handle) {
        return false;
    }
    $content = '';
    $bytesRead = 0;
    while (!gzeof($handle)) {
        $chunk = gzread($handle, 8192);
        if ($chunk === false) {
            gzclose($handle);
            return false;
        }
        $content .= $chunk;
        $bytesRead += strlen($chunk);
    }
    gzclose($handle);
    return ['content' => $content, 'bytes' => $bytesRead];
}
$result = readGzFileWithCheck('archive.gz');
if ($result) {
    echo "Прочитано {$result['bytes']} байт";
}
?>
Прочитано 15234 байт
Пример 2: Чтение нескольких gz-файлов в цикле с обработкой ошибок
Пример php
<?php
$files = ['log1.gz', 'log2.gz', 'missing.gz'];
foreach ($files as $file) {
    echo "Обработка файла: {$file}\n";
    $gz = @gzopen($file, 'r');
    if (!$gz) {
        echo "  Не удалось открыть файл\n";
        continue;
    }
    $lineCount = 0;
    while (!gzeof($gz)) {
        $line = gzgets($gz);
        if ($line !== false) {
            $lineCount++;
        }
    }
    gzclose($gz);
    echo "  Прочитано строк: {$lineCount}\n";
}
?>
Обработка файла: log1.gz
  Прочитано строк: 150
Обработка файла: log2.gz
  Прочитано строк: 89
Обработка файла: missing.gz
  Не удалось открыть файл
Пример 3: Использование вместе с ftell() (для несжатых потоков) и аналогом
Пример php
<?php
// Для gz-файлов нет прямой функции gztell(), но можно эмулировать
$gzfile = gzopen('large.gz', 'r');
$position = 0;
$chunkSize = 512;
while (!gzeof($gzfile)) {
    $buffer = gzread($gzfile, $chunkSize);
    $position += strlen($buffer);
    echo "Текущая позиция в распакованных данных: {$position} байт\n";
    // Условие выхода по дополнительному критерию
    if ($position > 5000) {
        echo "Достигнут лимит в 5000 байт\n";
        break;
    }
}
gzclose($gzfile);
?>
Текущая позиция в распакованных данных: 512 байт
Текущая позиция в распакованных данных: 1024 байт
...
Достигнут лимит в 5000 байт

PHP gzeof function comments

En
Gzeof Test for EOF on a gz-file pointer