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

Тема в разделе "PHP", создана пользователем qwr938, 2 ноя 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. qwr938

    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 не происходит). Подскажите, как исправить ситуацию.
     
  2. sartiii

    sartiii Постоялец

    Регистр.:
    17 сен 2008
    Сообщения:
    105
    Симпатии:
    17
    Файл нужно открывать на чтение и запись в бинарном режиме.
    Так же можно для записи в файл использовать функцию file_put_contents вместо связки fopen+ fputs + fclose.
     
  3. Jeckerson

    Jeckerson Постоялец

    Регистр.:
    26 июл 2009
    Сообщения:
    56
    Симпатии:
    6
    Конечно не проходит.
    Gz - Gzip Compressed Archive, а архивы нужно распаковывать для начала чтобы изменить там инфу :)
    Zip раздел на офф сайте тебе в помощь - тыц
    Так же там есть функции запаковки.
     
  4. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    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);
     
    qwr938 нравится это.
  5. qwr938

    qwr938 Постоялец

    Регистр.:
    13 авг 2008
    Сообщения:
    60
    Симпатии:
    1
    Код работает, спасибо. Проблема в том, что у меня gz-файл весит 80 МБ, а в распакованном виде 400 МБ. Использую следующий код:
    PHP:
    ini_set('memory_limit''1500M');
    $gz_file 'file.txt.gz';
    $zp gzopen($gz_file,"r");
    $file gzread($zp400*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($zp600*1024*1024);
    то вылезает ошибка
    Код:
    Fatal error: Out of memory (allocated 951058432) (tried to allocate 321073551 bytes) on line $file = str_replace("XXX","YYY",$file);
     
  6. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    в таком случае, только с 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);
     
    qwr938 нравится это.
  7. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    735
    Симпатии:
    261
    Если у тебя внутри этого .gz текстовый файл, то намного удобнее будет юзать
    PHP:
    gzgets()
    и обрабатывать файл построчно, чем возиться со скользящим окном чтоб не пропустить чего-нибудь на границе твоих gzread().

    Я не знаю, что конкретно ты с файлом делаешь, но вот банальный пример "заменить XXX на YYY" может не найти XXX если оно попало на границу буфера и XX прочитался в первый присест, а X во второй. Лечится это скользящим окном размера не меньше длины XXX, но это гемор. С gzgets все в сто раз проще.
     
  8. qwr938

    qwr938 Постоялец

    Регистр.:
    13 авг 2008
    Сообщения:
    60
    Симпатии:
    1
    А как тогда будет выглядеть этот код с использованием 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.
     
Статус темы:
Закрыта.