Gzgets: примеры (PHP)
gzgets(resource $stream, ?int $length = null): string|falseФункция gzgets в PHP
gzgets — это встроенная PHP функция для построчного чтения данных из файла, сжатого с использованием алгоритма gzip. Она является частью модуля Zlib и применяется в ситуациях, когда необходимо обрабатывать большие сжатые файлы без полной распаковки в память. Функция полезна для лог-файлов, дампов баз данных или других текстовых ресурсов, хранящихся в сжатом виде.
Функция принимает до трёх параметров:
- $stream (обязательный) — ресурс, полученный после успешного открытия gzip-файла с помощью функции gzopen(). Указывает на сжатый поток для чтения.
- $length (необязательный) — максимальное количество байт для чтения. Если аргумент опущен или равен null, функция будет считывать данные до достижения конца строки или конца файла (EOF). Ограничение длины помогает управлять потреблением памяти.
- $mode (необязательный) — редко используемый параметр, который может влиять на обработку потока. Обычно не требуется для большинства задач.
Функция возвращает строку до $length - 1 байт, считанную из файла, или false в случае ошибки или достижения конца файла.
Примеры работы с gzgets
Чтение всего файла строка за строкой без указания длины:
<?php
$handle = gzopen('example.txt.gz', 'r');
if ($handle) {
while (($line = gzgets($handle)) !== false) {
echo $line;
}
gzclose($handle);
}
?>Первая строка файла. Вторая строка текста. ...
Считывание строк с указанием максимального количества байт:
<?php
$handle = gzopen('example.txt.gz', 'r');
if ($handle) {
echo gzgets($handle, 10); // Считает до 9 байт или до символа новой строки
gzclose($handle);
}
?>Первая ст
Альтернативы в PHP
Функция gzfile() читает весь сжатый файл и возвращает массив строк. Подходит для небольших файлов, так как загружает все данные в память.
$lines = gzfile('example.txt.gz'); // Массив строкfile_get_contents() в сочетании с потоковыми контекстами или обёрткой compress.zlib:// позволяет прочитать весь сжатый файл в одну строку.
$content = file_get_contents('compress.zlib://example.txt.gz');Использование потоковых обёрток позволяет применять стандартные функции для работы с файлами, например fgets(), к сжатым данным без явного вызова функций модуля Zlib.
$handle = fopen('compress.zlib://example.txt.gz', 'r');
$line = fgets($handle); // Чтение строки
fclose($handle);Аналоги в других языках
В Python для работы с gzip используется модуль gzip. Открытие файла аналогично работе с обычными файлами.
import gzip
with gzip.open('example.txt.gz', 'rt') as f:
line = f.readline() # Чтение одной строки
# или построчное чтение всего файла
for line in f:
print(line)В Node.js требуется сначала создать поток для чтения и распаковки, затем читать данные построчно с помощью модуля readline.
const zlib = require('zlib');
const fs = require('fs');
const readline = require('readline');
const fileStream = fs.createReadStream('example.txt.gz');
const gunzip = zlib.createGunzip();
const rl = readline.createInterface({
input: gunzip
});
rl.on('line', (line) => {
console.log(line);
});
fileStream.pipe(gunzip);MySQL не имеет прямой аналогии для построчного чтения сжатых файлов на стороне СУБД. Однако, можно загружать сжатые файлы с помощью команды LOAD DATA INFILE при условии, что клиентская сторона поддерживает распаковку.
Типичные ошибки
Попытка чтения из некорректного ресурса приводит к предупреждениям и false.
<?php
$line = gzgets(false); // Неверно
?>Warning: gzgets() expects parameter 1 to be resource, bool given
Использование простого сравнения с false без учёта возможности пустой строки.
<?php
while ($line = gzgets($handle)) { // Пустая строка тоже будет считана как false
// ...
}
?>Корректный способ — строгое сравнение:
while (($line = gzgets($handle)) !== false) { ... }Незакрытый ресурс может привести к утечке памяти.
Изменения в версиях PHP
В PHP 8.0.0 параметр $length стал опциональным (раньше требовалось указывать). Теперь можно передавать null для чтения всей строки без ограничений по длине.
// До PHP 8.0
$line = gzgets($handle, 1024); // Длина обязательна
// Начиная с PHP 8.0
$line = gzgets($handle); // Корректно, читает до конца строкиРасширенные примеры
Чтение и парсинг сжатого CSV файла построчно.
<?php
$handle = gzopen('data.csv.gz', 'r');
if ($handle) {
while (($line = gzgets($handle)) !== false) {
$fields = str_getcsv($line);
// Обработка массива $fields
print_r($fields);
}
gzclose($handle);
}
?>Создание генератора для эффективного чтения больших файлов.
<?php
function readGzLines(string $filename): Generator {
$handle = gzopen($filename, 'r');
if (!$handle) return;
try {
while (($line = gzgets($handle)) !== false) {
yield $line;
}
} finally {
gzclose($handle);
}
}
foreach (readGzLines('huge.log.gz') as $line) {
// Обработка каждой строки
}
?>Использование gzgets для чтения строк из сжатого бинарного файла с фиксированными заголовками.
<?php
$handle = gzopen('packed.bin.gz', 'rb'); // Бинарный режим
$header = gzgets($handle, 100); // Чтение заголовка длиной 100 байт
// Дальнейшая обработка
?>