rivin poisto tiedostosta

neon 03.01.04 12:39

3 tapaa poistaa rivi tiedostosta

 Tekstiversio  Arvo: 4 (6 ääntä)  Äänestä: +  -
<?PHP

/**
    Kuinka tuhota jokin tietty rivi tiedostosta PHP:llä.
    Seuraavassa kolme erillaista tapaa toteuttaa kyseinen operaatio, siihen mikä
    tavoista on parempi en ota kantaa.
    Kuitenkin tapa 3 on suotava vain suurille tiedostoille ja tavat 1 ja 2 pienemmille.
**/


$tiedosto = "/my/path/my.file"; // tiedosto josta etsitään
$pattern = "somerow"// mitä etsitään
$matchCount = null;    // kuinka monta osuumaa, null jos kaikki mahdolliset

/////////////////////////////////////////////////////////////

/* tapa 1 */

if(($fp = @fopen($tiedosto,"r+")) == false) {
    exit("Tiedostoa $tiedosto ei voitu avata."); // tiedostoa ei ole olemassa tai siihin ei ole oikeuksia
}

$buffer = '';
$count = 0;

while(($row = fgets($fp,8192)) != '') {
    if(strpos($row,$pattern)) { // löytyykö haettavaa tältä riviltä
        $count++;
        if($count == $matchCount)  // onko saavutettu tuloksien enimmäinmäärä, jos on niin lopetetaan silmukka

            break;
        continue;
    }
    $buffer .= $row; // lisätään rivi puskuriin
}
// tyhjennetään tiedosto
ftruncate($fp,0);
// kirjoitetaan uusi sisältö
fwrite($fp,$buffer);
fclose($fp);

/////////////////////////////////////////////////////////////

/* tapa 2 */
       
if(($buffer = @file($tiedosto)) == false) {
    exit("Tiedostoa $tiedosto ei voitu avata."); // tiedostoa ei ole olemassa tai siihin ei ole oikeuksia
}

$rows = count($buffer); //rivien määrä
$count = 0;

for($i = 0; $i < $rows ; $i ++) {
    if(strpos($buffer[$i],$pattern)) { // löytyykö haettavaa merkkijonoa tältä riviltä
        unset($buffer[$i]); // jos löytyy niin poistetaan haluttu rivi araysta
        $count++;
        if($count == $matchCount) // onko saavutettu tuloksien enimmäinmäärä, jos on niin lopetetaan silmukka
            break;
    }
}

$buffer = implode('',$buffer); // yhdistetään rivit jälleen yhdeksi stringiksi ja kirjoitetaan se tiedostoon
$fp = fopen($tiedosto,"w");
fwrite($fp,$buffer);
fclose($fp);

/////////////////////////////////////////////////////////////

/* tapa 3 */

if(($fp = @fopen($tiedosto,"r+")) == false) {
    exit("Tiedostoa $tiedosto ei voitu avata."); // tiedostoa ei ole olemassa tai siihin ei ole oikeuksia
}
/*
    tarvitaan väliaikaistiedosto
*/

$temp = tempnam("/tmp","temp");

if(($temp_fp = @fopen($temp,"w")) == false) {
    exit("Tiedostoa $temp ei voitu avata.");
}

$count = 0;

while(($row = fgets($fp,8192)) != '') {
    if(strpos($row,$pattern)) { // löytyykö haettavaa tältä riviltä
        $count++;
        if($count == $matchCount) // onko saavutettu tuloksien enimmäinmäärä, jos on niin lopetetaan silmukka
            break;
        continue;
    }
    fwrite($temp_fp,$row);
}
fclose($fp);
copy($tiedosto,$tiedosto.".bak");
if(rename($temp,$tiedosto) === false) { // nimeys epäonnistui, kokeillaan seuraavaa tapaa
    if(copy($temp,$tiedosto) == false) {
        unlink($temp);
        exit("Failure!");
    }
    unlink($temp);
}
?>

Moschops 12:41 3.1.04 
Tätä mä olen aiina halunnut!
Jukoh 12:49 3.1.04 
Huhhuh, jos vaan tyytyis SQL:ään :)
Moschops 12:51 3.1.04 
SQL saks
renni 17:52 3.1.04 
Ihan kiva mutta onneksi näitä harvemmin tarvitsee. SQL rokkaa.
Kryil 12:21 5.1.04 
Ihan kiva.
Tapa 3:n temppifilun uudelleennimeämisessä on pieni heikkous, nimittäin jos kopiointi epäonnistuu niin kaikki data häviää. Tämä ei tiettävästi ole hyvä juttu.
neon 16:23 5.1.04 
Pahoitteluni, alkuperäisen tiedoston unlinkkaus oli jäänyt tuonne vahingossa. Korjattu.
Basic 18:30 31.5.06 
Kiitos! Juuri tätä minä tarvitsin!
eis 15:35 27.7.06 
if(strpos($row,$pattern)) { // löytyykö haettavaa tältä riviltä

Jos haettava on rivin alussa, strpos tietty palauttaa nollan joka evaluoituu falseksi.
Eli pitäis toki olla muodossa if (strpos(x,y) !== false)