Удаление раздела файла в PHP? - PullRequest
0 голосов
/ 20 января 2012

Я новичок в PHP, и я все еще пытаюсь выработать правильные методы обработки файлов. Я обычно в порядке с методом проб и ошибок, но когда дело доходит до удаления и изменения данных, я всегда хочу быть в безопасности.

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

Я только что проверил это, и оно сработало, но я хотел бы сначала запустить его более опытными программистами:

function deletesection($start,$len){
    $pos=0;
    $tmpname=$this->name."tmp.tmp";
    $tmpf=fopen($tmpname,"wb+");
    rewind($tmpf);
    $h=fopen($this->name,"rb");
    rewind($h);
    while(!feof($h)){
        $this->xseek($h,$pos);
        $endpos = $pos+1000;
        if($endpos>$start && $pos<$start+$len){
            $readlen=$start-$pos;
            $nextpos=$start+$len;
        }
        else{
            $readlen=1000;
            $nextpos=$pos+1000;
        }
        fwrite($tmpf,fread($h,$readlen));
        $pos=$nextpos;
    }
    fclose($h);
    unlink($this->name);
    rename($tmpname,$this->name);
}

Это внутри класса, где свойство "name" является путем к файлу.

Я записываю файл по 1000 байт за раз, потому что я получаю ошибки о превышении максимального объема памяти при тестировании с файлами размером более 30 МБ.

1 Ответ

1 голос
/ 20 января 2012

Я быстро взглянул на ваш код - кажется немного сложным, копирование всего файла будет менее эффективным, если удаляемый раздел мал по сравнению с общим размером файла ...

function deletesection($filename, $start, $len)
{
 $chunk=49128;
 if (!is_readable($filename) || !is_writeable($filename) || !is_file($filename)) {
   return false;
 }
 $tfile=tempnam(); // used to hold stuff after the section to delete
 $oh=fopen($tfile, 'wb');
 $ih=fopen($filename, 'rb');
 if (fseek($ih, $start+$len)) {
  while ($data=fgets($ih, $chunk) && !feof($ih) {
     fputs($oh,$data);
  }
  fclose($oh); $oh=fopen($tfile, 'rb'); 
       // or could just have opened it r+b to begin with
  fseek($ih, $start, SEEK_SET);
  while ($data=fgets($oh, $chunk) && !feof($oh) {
     fputs($ih, $data);
  }
 }
 fclose($oh);
 fclose($ih);
 unlink($tfile);
 return true;  
}

Я полагаю, что было бы также возможно сделать это, изменив файл на месте (т.е. не используя второй файл), используя один дескриптор файла - но код получился бы немного запутанным и потребовал бы много поисков (затем ftruncate ).

Примечание: использование файлов для управления данными с помощью PHP (и большинства других языков в многопользовательском контексте) не очень хорошая идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...