Редактирование gz-файлов с помощью PHP

Статус
В этой теме нельзя размещать новые ответы.

qwr938

Постоялец
Регистрация
13 Авг 2008
Сообщения
60
Реакции
1
Имеется файл name.gz. Хочу изменить его содержимое с помощью функции str_replace и сохранить изменения.
Для txt-файла код может быть таким:
PHP:
$content = file_get_contents("name.txt");
$content = str_replace("XXX", "YYY", $content);
$fp = fopen("name.txt ", "w");
fputs ($fp, $content);
fclose ($fp);
С gz-файлом подобный код не работает (замены XXX на YYY не происходит). Подскажите, как исправить ситуацию.
 
Файл нужно открывать на чтение и запись в бинарном режиме.
Так же можно для записи в файл использовать функцию file_put_contents вместо связки fopen+ fputs + fclose.
 
Конечно не проходит.
Gz - Gzip Compressed Archive, а архивы нужно распаковывать для начала чтобы изменить там инфу :)
Zip раздел на офф сайте тебе в помощь -
Так же там есть функции запаковки.
 
PHP:
$gz_file = 'file.txt.gz';

$zp = gzopen($gz_file,"r");
$file = gzread($zp,1024*1024);
gzclose($zp);

$file = str_replace("XXX","YYY",$file);

$zp=gzopen($gz_file,"w9");
gzwrite($zp,$file);
gzclose($zp);
 
Код работает, спасибо. Проблема в том, что у меня gz-файл весит 80 МБ, а в распакованном виде 400 МБ. Использую следующий код:
PHP:
ini_set('memory_limit', '1500M');
$gz_file = 'file.txt.gz';
$zp = gzopen($gz_file,"r");
$file = gzread($zp, 400*1024*1024);
gzclose($zp);
$file = str_replace("XXX","YYY",$file);
$zp=gzopen($gz_file,"w9");
gzwrite($zp,$file);
gzclose($zp);
Всё работает. Однако memory_limit в 1500 МБ звучит несколько пугающе. Подскажите, пожалуйста, как подправить код, чтобы избежать использования такого большого memory_limit. Вроде, можно считывать файл по строкам или кусками. Но я не знаю, как это внедрить в данный код.

Если поставить
PHP:
ini_set('memory_limit', '1000M');
то вылезает ошибка
Код:
Fatal error: Allowed memory size of 1048576000 bytes exhausted (tried to allocate 321073551 bytes) on line $file = str_replace("XXX","YYY",$file);

Если поставить
PHP:
$file = gzread($zp, 600*1024*1024);
то вылезает ошибка
Код:
Fatal error: Out of memory (allocated 951058432) (tried to allocate 321073551 bytes) on line $file = str_replace("XXX","YYY",$file);
 
в таком случае, только с feof, т.е. обработка частями по 1 Mb и дозапись в архив-результат
PHP:
$gz_file = 'file.txt.gz';
$gz_res = 'res_file.txt.gz';

$zp=gzopen($gz_file,"r"); $zp2=gzopen($gz_res,"w9");

while(!feof($zp)) {
$f_part = gzread($zp,1024*1024);
$f_part = str_replace("XXX","YYY",$f_part);
gzwrite($zp2,$f_part);	
}

gzclose($zp); gzclose($zp2);
 
Если у тебя внутри этого .gz текстовый файл, то намного удобнее будет юзать
PHP:
gzgets()
и обрабатывать файл построчно, чем возиться со скользящим окном чтоб не пропустить чего-нибудь на границе твоих gzread().

Я не знаю, что конкретно ты с файлом делаешь, но вот банальный пример "заменить XXX на YYY" может не найти XXX если оно попало на границу буфера и XX прочитался в первый присест, а X во второй. Лечится это скользящим окном размера не меньше длины XXX, но это гемор. С gzgets все в сто раз проще.
 
С gzgets все в сто раз проще.
А как тогда будет выглядеть этот код с использованием gzgets()? Я что-то не догоняю :nezn:. Напишите, пожалуйста, если не трудно.
Возник ещё один вопрос: как можно скачать большой gz-файл, находящийся по адресу site.ru/file.txt.gz, в папку со скриптом на моём сервере?
Пробовал сделать так:
PHP:
copy('http://www.site.ru/file.txt.gz', '/');
Выдаётся ошибка:
Код:
Warning: copy(http://www.site.ru/file.txt.gz) [function.copy]: failed to open stream: HTTP request failed!
Работаю на локальном сервере XAMPP.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху