Wie zu überwachen Textdatei und kontinuierlich ausgegeben Inhalt in eine textbox
Mache ich ein Programm, dass die Kontrollen einen game-server. Eine der Funktionen, die ich mache, ist eine live-server-logfile monitor.
Gibt es ein logfile (eine einfache Textdatei), der bekommt vom server aktualisiert, wie es läuft.
Wie kann ich ständig prüfen, ob die Protokolldatei und geben Sie den Inhalt in eine RichTextBox?
Habe ich diese einfache Funktion einfach versuchen, die Inhalte des Protokolls.
Es wird natürlich nur der text Zeile für Zeile und Ausgabe, die es zu meiner textbox.
Es wird auch sperren Sie das Programm so lange wie die Schleife läuft, so dass ich weiß, es ist nutzlos.
public void ReadLog()
{
using (StreamReader reader = new StreamReader("server.log"))
{
String line;
//Read and display lines from the file until the end of the file is reached.
while ((line = reader.ReadLine()) != null)
{
monitorTextBox.AppendText(line + "\n");
CursorDown();
}
}
}
Aber wie würden Sie gehen über die Lösung der live-überwachung so einfach wie möglich?
* EDIT *
Ich bin mit Prescots Lösung. tolle Sachen.
Im moment bin ich mit einem sstreamreader der text aus der Datei in mein Textfeld. Ich lief in das problem ist, dass, wenn ich versuchte, den Zugriff auf die gui-Bedienelemente in meinem event-handler das Programm einfach beendet ohne Fehler oder Warnungen.
Fand ich heraus, dass es hat zu tun mit dem Durchzug. Ich löste das Problem so:
private void OnChanged(object source, FileSystemEventArgs e)
{
if (monitorTextField.InvokeRequired)
{
monitorTextField.Invoke((MethodInvoker)delegate { OnChanged(source, e); });
}
else
{
StreamReader reader = new StreamReader("file.txt");
monitorTextField.Text = "";
monitorTextField.Text = reader.ReadToEnd();
reader.Close();
CursorDown();
}
}
Nun, mein problem ist nur, dass die file.txt die vom server verwendet werden, so kann ich nicht darauf zugreifen, da es "Wesen von einem anderen Prozess verwendet". Ich kann nicht kontrollieren, dass dabei.. also vielleicht bin ich kein Glück.
Aber die Datei kann im Editor geöffnet werden, während der serevr läuft, also irgendwie muss es möglich sein. Vielleicht kann ich eine temp-Kopie der Datei, wenn es updates und Lesen Sie die Kopie. Weiß nich...
InformationsquelleAutor Christoffer | 2012-03-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Check-out die System.IO.FileSystemWatcher Klasse:
Edit: wenn Sie wissen, einige details über die Datei, die Sie verarbeiten könnte der effizienteste Weg, um die Letzte Zeile. Zum Beispiel, vielleicht, wenn Sie die Datei Lesen, können Sie wischen Sie heraus, was Sie gelesen haben, also das nächste mal aktualisiert, greifen Sie einfach, was da ist-und Ausgang. Vielleicht kennen Sie eine Zeile Hinzugefügt wird, dann kann der code sofort springen, um die Letzte Zeile der Datei. Etc.
ah ja sorry, ich schrieb, dass die umliegenden code super schnell. Können Sie rip out the watcher-code und setzen Sie ihn, Wann immer es angemessen ist in Ihrem code, dass es nicht in eine Armbanduhr () - Funktion, die ich schon oben.
Danke!!! Ich habe gerade einige Infos zu der ersten Frage (neu hier.. Bin ich gegen alle Regeln damit?)
Wenn Ihre Frage beantwortet wurde, werden Sie wahrscheinlich wollen, um Sie zu markieren, als beantwortet, und starten Sie eine neue Frage. Es macht es cleaner
InformationsquelleAutor Prescott
Obwohl die
FileSystemWatcher
ist die einfachste Lösung, die ich gefunden haben, es zu sein unzuverlässig in der Realität.. oft eine Datei kann aktualisiert werden, mit neuen Inhalten, sondern dieFileSystemWatcher
nicht ein Ereignis ausgelöst, bis Sekunden später und oft nie.Die einzige zuverlässige Möglichkeit, die ich gefunden habe, um diesen Ansatz zu überprüfen, um änderungen an der Datei auf einer regelmäßigen basis, mit einem
System.Timers.Timer
- Objekt und überprüfen Sie die Größe der Datei.Habe ich eine kleine Klasse geschrieben, die zeigt, das hier verfügbar ist:
https://gist.github.com/ant-fx/989dd86a1ace38a9ac58
Beispiel Für Die Verwendung
Ist die einzige wirkliche Nachteil hier (abgesehen von einem leichten performance-Verzögerung, verursacht durch Datei-Größe überprüfen) ist, weil es verwendet eine
System.Timers.Timer
der Rückruf kommt aus einem anderen thread.Wenn Sie eine Windows Forms-oder WPF-Anwendung könnten Sie leicht ändern, die Klasse zu akzeptieren
SynchronizingObject
stellen, die die event-handler-Ereignisse genannt werden, die aus dem gleichen thread.InformationsquelleAutor antfx
Als @Prescott vorgeschlagen, verwenden Sie eine
FileSystemWatcher
. Und stellen Sie sicher, öffnen Sie die Datei mit der entsprechenden FileShare - Modus (FileShare.ReadWrite
geeignet scheint), denn die Datei kann noch geöffnet werden, durch den server. Wenn Sie versuchen, die Datei exklusiv öffnen, während es noch von einem anderen Prozess verwendet, der öffnen-operation fehl.Auch, um ein bisschen die Leistung, die Sie sich erinnern konnte, die Letzte position, bis zu der Sie bereits gelesen haben, die Datei und liest nur die neuen Teile.
Ich denke, für die Suche nach einer bestimmten position, müssen Sie den Zugriff auf die zugrunde liegenden
FileStream
direkt (über diePosition
- Eigenschaft). So erstellen Sie zunächst dieFileStream
, gehen Sie auf die richtige position, erstellen Sie einStreamReader
oben auf dem stream, die Daten Lesen und dann die endgültige position wieder von derFileStream
. (Ich habe es nicht ausprobiert, ich hoffe es funktioniert wie beschrieben ...)InformationsquelleAutor MartinStettner
Versuchen Sie, ein Timer und die
Timer.Tick
legen Sie ein Intervall von 1 Sekunde. AufTimer.Tick
Sie die Funktion ausführen.InformationsquelleAutor Mr Wednesday
Verwenden, diese Antwort auf einen anderen post c# - kontinuierlich Datei Lesen.
Dieser ist ziemlich effizient, und es prüft einmal pro Sekunde ob die Datei die Größe hat sich verändert.
Können Sie entweder führen Sie es auf einem anderen thread (oder konvertieren async-code), in jedem Fall aber würden Sie brauchen, um marshall den text wieder, den Faden zum Anhängen an die textbox.
InformationsquelleAutor Todd