Laden...

Zeile von Textdatei bearbeiten und dann löschen

Erstellt von maeva vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.051 Views
Thema geschlossen
M
maeva Themenstarter:in
5 Beiträge seit 2014
vor 10 Jahren
Zeile von Textdatei bearbeiten und dann löschen

Hallo,
ich habe viele Zeilen in einer Textdatei. möchte ich die erste zeile lesen, bearbeiten und wenn die Bearbeitung erfolgsreich war, die zeile löschen und die nächste zeile bearbeiten. Wenn die bearbeitung nicht erfolgsreich die zeile nicht löschen aber trotzdem die nächste zeile weitermachen. mein code funktioniert schon mal gut aber nur die zeile wird nicht gelöscht.

try
{
    f_file = new System.IO.StreamReader(s_sqlfile);
}
catch
{
    continue;
}

while ((s_sqlfileline = f_file.ReadLine()) != null)
{
    Bearbeitung();
    var lines = File.ReadAllLines(s_sqlfile);
    File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray());
}
f_file.Close();

Die zeile File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray()); wird nicht ausgeführt. ich weiss nicht warum.
kann jemand mir helfen
vielen Dank im voraus

W
872 Beiträge seit 2005
vor 10 Jahren

f_file.Close();

sollte vor

File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray());

stehen.
Welche Exception bekommst Du denn genau?

2.078 Beiträge seit 2012
vor 10 Jahren

Bekommst du überhaupt eine Exception, oder tut diese Zeile einfach nicht das, was du erwartest?

Skip ist aber vermutlich sowieso die falsvche Methode, da sie nur die angegebene Anzahl Zeilen überspringt. Wenn du nun alle Zeilen aus der Datei liest, dann nach Skip wieder in die Datei schreibst, fehlt jedes mal nur die erste Zeile, nicht die, die du weg haben willst.

Mir ist nicht bekannt, wie man eine Zeile direkt löschen kann, aber ich hätte eine andere Idee:

const string tempFileExtensions = ".temp";

var fileName = @"c:\directory\file.extension";
var tempFileName = fileName + tempFileExtensions;

var lines = File.ReadLines(fileName).Where(line => !DoWorkWithLines(line));

File.Create(tempFileName);
File.WriteAllLines(tempFileName, lines);

File.Delete(fileName);
File.Copy(tempFileName, fileName);

In DoWorkWithLines(string) findet dann die weitere Bearbeitung statt und als Rückgabeparameter erhältst du ein bool, der angibt, ob die Bearbeitung erfolgreich war, oder nicht.

Probiere das doch mal aus, ich weiß aber gerade nicht, wie schnell das ist, bei sehr großen Dateien, vielleicht gibt es da auch eine performantere Lösung.
Ich denke aber, das sollte zumindest performanter sein, als deine bisherige Idee.

Edit:

Ich lese gerade die Antwort von weismat genauer:

Wenn das

f_file.Close();

vor dem

File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray());

dann schließt du den Stream noch in der Schleife, wo er bei ReadLine benötigt wird. Spätestens dann bekommt sie eine Exception.

Ich nutze das aber gleich mal und werfe das Wort using in den Raum. Dann musst du dich nicht mehr um das Disposen des Streams kümmern.

M
maeva Themenstarter:in
5 Beiträge seit 2014
vor 10 Jahren

Hallo,
Vielen Dank für euere Antwort.
Die Lösüng war

 f_file.Close();

vor die zeile

File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray());

zu schreiben.
nochmal danke.
MfG

2.078 Beiträge seit 2012
vor 10 Jahren

?

Ich verstehe gerade nicht so ganz, wie das funktionieren kann.
Der Stream f_file wird dann ja schon in der while-Schleife geschlossen, in deren Bedingung die Zeilen aus ihm gelesen werden.

Sicher, dass das funktioniert?
Vielleicht steh ich grad total neben der Mütze, aber meines Wissens nach müsste das eine Exception geben.

M
maeva Themenstarter:in
5 Beiträge seit 2014
vor 10 Jahren

ja Palladin007 hat recht. das habe ich so gemacht.


try
{
    f_file = new System.IO.StreamReader(s_sqlfile);
}
catch
{
    continue;
}

while ((s_sqlfileline = f_file.ReadLine()) != null)
{
    Bearbeitung();
    try
    {
        //bei if(true) bedingung, dass die Bearbeitung erfolgsreich war
        if (s_temp != null && s_temp.Length > 0)
        {
            f_file.Close();

            //remove line from log
            var lines = File.ReadAllLines(s_sqlfile);
            File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray());
            f_file = new System.IO.StreamReader(s_sqlfile);
        }
    }
    catch
    {
        continue;
    }
}
f_file.Close();
M
maeva Themenstarter:in
5 Beiträge seit 2014
vor 10 Jahren

Hallo Leute,
Ich treffe heute nochmal ein Problem im meinem Programmcode.
Die Linie File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray()); löscht mir immer die erste zeile von meinem Textdatei. Weiss jemand viellleicht warum?
wenn die Bedingung if (s_temp != null && s_temp.Length > 0) bei der erste zeile false ist, die linie File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray()); wird nicht ausgeführt. wenn diese bedingung bei der zweite zeile true ist, die linie File.WriteAllLines(s_sqlfile, lines.Skip(1).ToArray()); wird ausgeführt.
Es sollte diese zweite zeile im Textdatein löschen, nicht die erste zeile.
Frage: warum wird immer die erste zeile von textdatei gelöscht?

Vielen Dank im vorraus

16.807 Beiträge seit 2008
vor 10 Jahren

Weil Du Skip(1) verwendest.
Bitte erkunde Dich doch mal, was Dein Code überhaupt tut. Dafür ist die Doku da :rtfm:
Beachte auch [Hinweis] Wie poste ich richtig? 1.1

S
417 Beiträge seit 2008
vor 10 Jahren

Die Datei nach jeder Zeilenbearbeitung neu zu schreiben ist nicht sinnvoll.
Mach es so wie Palladin007 es in seinem ersten Post beschrieben hat und filtere einfach die Zeilen die beibehalten werden sollen und schreibe diese dann gesammelt auf die Platte.
Du musst nur noch die von Palladin007 genannte Methode DoWorkWithLines ordentlich implementieren.

M
maeva Themenstarter:in
5 Beiträge seit 2014
vor 10 Jahren

hallo,
Ich würde anders vorgehen. wenn die Bearbeitung erfolgreich war, die Zeile in texdatei umbenennen und ersetzen. dann kann ich am ende mit dieser Umbenennung die Zeile filtern und löschen.
so habe ich den code gemacht.

if (s_temp != null && s_temp.Length > 0)
{
s_line = s_line.Replace(s_line, "!" + s_line);
                                                       
 //File.Move(s_line, s_line.Replace(s_line, "!" + s_line));
   StreamWriter outputStreamWriter = File.CreateText( @"C:\log.txt");
  outputStreamWriter.Write(s_line);
 outputStreamWriter.Close();
}

Aber alle Zeile im textdatei wird gelöscht und durch die neue zeile ersetzt.
wie kann ich nur die Zeile, die im Bearbeitung ist, ersetzen
vielen Dank

Hinweis von herbivore vor 10 Jahren

Datei einlesen, im Hauptspeicher die gewünschte Zeile ändern, Datei wieder komplett schreiben.

Das wurde nun oft genug erklärt. Die Umsetzung fällt unter Grundlagen. Alle nötigen Methoden wurden genannt oder man kann sie leicht in der MSDN Doku finden. Die Ver- und Bearbeitung von Textdateien setzen wir als bekannt voraus.

Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1.1 und 1.1.

Thema geschlossen