Barney: Zeile aus Datei löschen

Folgendes Problem:

Versteh dieses scripz nicht so wirklich hab das online gefunden:
Möchte aus einer csv Datei eine Bestimmte Zeile löschen:
Die zu löschende Zeile steht in $ArtNr.
Wo muss ich das einbauen??

<?
$oldfile = "Stammdaten.csv";

$old = fopen($oldfile,"r");
flock($old, 1) or die("Kann die Quelldatei $oldfile nicht locken.");

$new = fopen($oldfile.".new","w");
flock($old, 2) or die("Kann die Zieldatei $newfile nicht locken.");

$lineno = 0;

while($line = fgets($old, 1024))
{
if($lineno++ == $zielzeile)
  continue;

fputs($new,$line);
}

fclose($old);

unlink($oldfile);
fclose($new);
rename($oldfile.".new",$oldfile);

?>

mfg Barney

  1. Wie wäre es, wenn du statt "$zielzeile" einfach "$ArtNr" schreibst?

    --
    EisFuX
    1. ja des funktioniert aber nicht
      keine Fehler aber auch keine Wirkung

      mfg

      1. hat sich erledigt danke

  2. Hello,

    Versteh dieses scripz nicht so wirklich hab das online gefunden:
    Möchte aus einer csv Datei eine Bestimmte Zeile löschen:
    Die zu löschende Zeile steht in $ArtNr.
    Wo muss ich das einbauen??

    Nochmal zum Sortieren:

    Du hast eine _echte_ CSV-Datei?
    Das CSV-Format lässt sich nur noch datensatzweise == zeilenweise mit fgetcsv() lesen, mit keiner anderen Funktion!

    Beim Lesen werden dann die einzelnen Elemente der Zeile (die Datenfelder) in ein Array übernommen.
    Mit CSV-Dateien möchte man i.d.R. eine einfache Lösung schaffen, eine Tabelle abzubilden. Da hier eine positionsbasierte Darstellung der Datenfelder stattfindet und keine namensbasierte, sollte also jede Zeile dieselbe Anzahl Felder in derselben Reihenfolge haben.
    Die Zeilenlänge ist dabei unerheblich.

    Das allererste Zeichen der Datei stellt i.d.R. den Feldbegrenzer dar.
    Dies wird dadurch verifiziert, dass es auch als letztes Zeichen vor dem Zeilenumbruch auftritt und bis dahin eine gerade Anzahl dieser Zeichen vorhanden war.
    Sind diese beiden Zeichen unterschiedlich, hat die CSV-Datei keine "Enclosures"

    PHP nennt das Ding "Enclosure". In der klassischen Datentechnik heißt es "Delimiter".

    Das Trennzeichen zwischen den eingesschlossen Feldern wird bei PHP "Delimiter" genannt, in der klassischen Datentechnik heißt es "Seperator". "CSV" heißt dort auch "SDF" (Standard Data Format).

    Es ist ganz praktisch, wenn man die drei Kenndaten der CSV-Datei weiß:

    • Field-Seperator     z.B. Komma         (,)
    • Field-Delimiter     z.B. Doppelhäkchen (")
    • Record-Seperator    z.B. Zeilenumbruch (\n)

    Man kann die Datei nun zeilenweise lesen und umkopieren in eine neue, oder man liest sie komplett ein in ein "Master-Array". Dazu benötigt man dann aber genügend Arbeitsspeicher.
    Die zweite Methode ist für Dateien bis ca. 1MB Größe in der PHP-Praxis vorzuziehen.

    Um nun eine spezielle Zeile austauschen zu können, musst Du also wissen, in welcher Spalte der gesuchte Begriff steht, und diese dann vergleichen.

    Wenn man die Datei umkopieren will, muss man die Quelle nach dem öffnen sperren. Dabei ist es wesentlich, dass man eine EXCLUSIVE Sperre versucht, da man die Daten der Datei zu verändern wünscht. Man kann aber nach dem erfolgreichen EXCLUSIVE-Sperren die Sperre ohne weiteres auf SHARED zurücknehmen, damit andere Prozesse während des Bearbeitungsvorganges weiterhin "informatives Lesen" betreiben können. Beim informativen Lesen können die Daten dirty sein, das bedeutet, nicht mehr in ihrer Gesamtheit zutreffen. Es ist aber in der Tagespraxis oft nicht erforderlich, sekundengenaue Daten zu haben. Nur eine Datenveränderung darf man auf der Grundlage von Dirty-Data nicht durchführen!

    Die Zieldatei kann man dann unter einem anderen Namen (am besten ein TMP-Name) anlegen.
    Wenn man einen eigenen Namen verwendet, muss man darauf achten, dass die Zieldatei noch nicht besteht. Das ereicht man am Besten mit fopen($zieldateiname,'xb'); also mit dem X-Modus. Dieser legt die neue Datei nur dann an, wenn sie noch nicht vorhanden war.

    Wenn alles geklappt hat, kannst Du mit dem Umkopieren loslegen. Die Zielzeile muss natürlich aus dem Array erst wieder nach den regeln von CSV zusammengebaut werden.

    Enclosures innerhalb der Arrayelemente (Felder) durch Verdoppelung maskieren, dann die Felder mit

    $zeile = $enclosure.explode($separator,$_record).$enclosure.CRLF;

    zusammenbauen und in die Zeiledatei wegschreiben.

    Um keine Namenslücke zu erzeugen, müsste man die Zieldatei nun eigentlich auf die Quelldatei schreiben, diese dann kürzen und anschließend die Zieldatei schließen und dann die ehemalige Quelle schließen. Dadurch wird das Handle wieder freigegeben, das Lock aufgehoben und die Daten sind die neuen.

    Es wird aber gerne meistens nur mit einem rename der Zieldatei gearbeitet. Um dies durchführen zu können, muss aber der Quelldateiname zuvor aus dem Directory gelöscht werden, was dann für Andere Instanzen des Scriptes zu einer kurzzeitigen _ungeschützten_ Namenslücke führt.

    Man muss hier also die Programmstabilität gegen den zusätzlichen Traffic im Filesystem abwägen.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau