Laden...

(anderweitig geöffnete) Textdatei in Echtzeit auslesen

Erstellt von cocacola vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.621 Views
C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren
(anderweitig geöffnete) Textdatei in Echtzeit auslesen

Hallo zusammen.
Dies ist mein erster Post.

Nun zu meinem Problem:
Ich will eine Textdatei, an die immer neue Zeilen angehängt wird möglichst in Echtzeit auslesen. So weit bin ich bis jetzt gekommen Ich benutze das Objekt FileSystemWatcher:


private void bt_start_Click(object sender, EventArgs e)
        {
            fsw_log.Path = @"G:\Games\MyServer\base\";
            fsw_log.Filter = "MyLogs.log";
            
        }

        private void fsw_log_Changed(object sender, FileSystemEventArgs e)
        {
            MessageBox.Show("test");
        }

Das Problem liegt darin, dass das changed event nur ausgelöst wird, wenn die datei manuell veraendert bzw überprüft wird.
Gibt es noch eine andere Möglichkeit?
Danke im Vorraus
cocacola

1.371 Beiträge seit 2004
vor 14 Jahren

Hi und willkommen im Forum!

Normal sollte die Änderung in der Datei immer angezeigt werden bzw. den Watcher auslösen. Wie wird die Datei denn bei dir geändert?

==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================

6.911 Beiträge seit 2009
vor 14 Jahren

Hallo,

setze die NotifyFilter-Eigenschaft auf Size oder LastWrite -> dann klappt es.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

Wie wird die Datei denn bei dir geändert?

Es ist die Logdatei eines Gameservers. Der Gameserver greift also permanent auf die Datei zu. Hoffe das beantwortet die Frage

setze die NotifyFilter-Eigenschaft auf Size oder LastWrite -> dann klappt es.

Ich habe alle NotifyFilter-Eigenschaften ausprobiert. Sie werden nur ausgelöst, wenn man manuell auf die Datei zugreift.

6.911 Beiträge seit 2009
vor 14 Jahren

wenn man manuell auf die Datei zugreift.

Bei mir gehts auch wenn die Datei von einem anderen Programm beschrieben wird.

Der FSW arbeitet meines Wissens nach nicht ganz zuverlässig - wie du sicher auch schon mitbekommen hast. Das Problem liegt bei Windows.

Alternativ könntest du mit einem Timer periodisch die Daten prüfen und einen Hash ermitteln (zB die Dateigröße) und diese vergleichen. Funktioniert sicher.
Es ist dabei auf die Zugriffsrechte zu achten. Dein Gameserver sollte keine exklusiven Rechte für die Datei haben.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

        private void timer1_Tick(object sender, EventArgs e)
        {
            logDatei = new FileInfo(@"G:\Games\myServer\base\myLogs.log");
            if (size1 = logDatei.Length)
            {
                string[] lines = File.ReadAllLines(@"G:\Games\myServer\base\myLogs.log");
                richTextBox1.Text = lines[lines.Length + 1];
                size = logDatei.Length;
            }
         }

Es wird die exception:

Der Prozess kann nicht auf die Datei "G:\Games\myServer\base\myLogs.log" zugreifen, da sie von einem anderen Prozess verwendet wird. ausgeworfen, wie du eben schon erwähnt hast. Wenn ich den StreamReader benutze erhalte ich die selbe Fehlermeldung.
Wie kann ich diesen Fehler beheben?

6.911 Beiträge seit 2009
vor 14 Jahren

Dein Gameserver sollte keine exklusiven Rechte für die Datei haben.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

Ja klar! Das hab ich schon verstanden ^^ Mein Problem liegt darin, wie ich das realisiere, weil ich das im Gameserver natürlich nicht einstellen kann.
Danke
cocacola

6.911 Beiträge seit 2009
vor 14 Jahren

Dachte es geht nicht, aber es gibt doch eine Möglichkeit:

Durch Verwendung der FileStream-Überladung bei welcher der FileShare angegeben werden.


string content = string.Empty;

using (System.IO.FileStream logFs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
{
	using (System.IO.StreamReader sr = new System.IO.StreamReader(logFs))
	{
		content = sr.ReadToEnd();
	}
}

Sollte es mit Read nicht gehen probier andere aus.

Sorry wegen vorhin.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

Schade... Die Fehlermeldung tritt weiterhin auf 😦
Trotzdem vielen Dank für deine Hilfe. Falls jemand doch noch eine Idee hat - bitte schreiben 😃
cocacola

6.911 Beiträge seit 2009
vor 14 Jahren

Hast du auch FileShare.ReadWrite probiert?

Wenn das auch nicht geht dann lügt die MSDN 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

Jaaa DANKE!
Es funktioniert! Super, echt vielen vielen Dank.
cocacola

C
252 Beiträge seit 2007
vor 14 Jahren

Also daran kanns nicht gelegen haben, denn der FileShare Parameter nur für das nachfolgende Öffnen/schreiben der Datei verantwortlich ist. Also wenn der Gameserver die Datei bereits geöffnet hat, dann sollte trotzdem die Exception fliegen.
siehe FileShare-Enumeration

Ermöglicht das nachfolgende Öffnen der Datei zum Lesen oder Schreiben.

Es hat vermutlich deshalb funktioniert, da dein Prozess die Datei zuerst geöffnet hat und dank FileShare es der Server dann ebenfalls konnte.

6.911 Beiträge seit 2009
vor 14 Jahren

Also daran kanns nicht gelegen haben, denn der FileShare Parameter...

Probiers aus -> die Empirie besätigt dass FileShare.ReadWrite verwendet werden muss damit es funktioniert.

Auf die MSDN ist halt nicht immer verlass bzw. wurde der Begriff "nachfolgend / subsequent" unglücklich gewählt. ?(

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
cocacola Themenstarter:in
9 Beiträge seit 2009
vor 14 Jahren

Es hat vermutlich deshalb funktioniert, da dein Prozess die Datei zuerst geöffnet hat und dank FileShare es der Server dann ebenfalls konnte.

Es funktioniert auch, wenn der Gameserver vor dem Programm auf die Datei zugreift.

1.361 Beiträge seit 2007
vor 14 Jahren

Hi,

meines Wissens muss die FileShare Option bei allen Zugriffen gesetzt sein.
Also sowohl beim zuerst Öffnenden, wie auch von allen nachfolgend Öffnenden.

(so ein bischen wie das CopyLeft-Prinzip 😉 )

U
1.688 Beiträge seit 2007
vor 14 Jahren

Hallo,

meines Wissens muss die FileShare Option bei allen Zugriffen gesetzt sein

wer zuerst die Datei öffnet, entscheidet, wie nachfolgende Prozesse die Datei öffnen dürfen - gar nicht, zum Lesen oder zum Lesen und Schreiben.
MSDN zu File.Open sagt z. B.: "Ein FileShare-Wert, der die Art des Zugriffs angibt, die andere Threads auf die Datei haben." Genauer ist da die Beschreibung von CreateFile im SDK.

Deshalb kann die Reihenfolge sehr wohl eine Rolle spielen.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo zusammen,

um den Spekulationen ein Ende zu setzen 😃 hier eine vollständige Liste aller zulässigen Kombinationen:

[PRE]FileAccess, FileShare (Thread 1)
   FileAccess, FileShare (Thread 2)

Read,       Read
   Read,       Read
   Read,       ReadWrite
Read,       Write
   Write,      Read
   Write,      ReadWrite
Read,       ReadWrite
   Read,       Read
   Read,       ReadWrite
   Write,      Read
   Write,      ReadWrite
   ReadWrite,  Read
   ReadWrite,  ReadWrite
Write,      Read
   Read,       Write
   Read,       ReadWrite
Write,      Write
   Write,      Write
   Write,      ReadWrite
Write,      ReadWrite
   Read,       Write
   Read,       ReadWrite
   Write,      Write
   Write,      ReadWrite
   ReadWrite,  Write
   ReadWrite,  ReadWrite
ReadWrite,  Read
   Read,       ReadWrite
ReadWrite,  Write
   Write,      ReadWrite
ReadWrite,  ReadWrite
   Read,       ReadWrite
   Write,      ReadWrite
   ReadWrite,  ReadWrite[/PRE]

Getestet wurde wie folgt: Der erste Thread öffnet eine (existierende) Datei (FileMode.Open) mit der jeweils angegebenen Kombination aus FileAcess und FileShare und hält diese offen. Dieses Öffnen funktioniert bei allen Kombinationen aus FileAccess und FileShare. Dann kommt der zweite Thread und versucht dieselbe Datei mit der jeweils angegebenen Kombination aus FileAcess und FileShare öffnen. Die Ausgabe von Thread 1 erfolgt linksbündig; die Ausgabe von Thread 2 erfolgt um drei Zeichen eingerückt. Eine Ausgabe erfolgt nur dann, wenn das Öffnen in Thread 2 erfolgreich ist. Im Umkehrschluss schlägt bei allen nicht genanten Kombinationen das Öffnen in Thread 2 fehl.

Die Liste ist symmetrisch, das heißt, wenn Thread 1 die Datei mit FA1, FS1 öffnet und dann das Öffnen aus Thread 2 mit FA2, FS2 klappt, dann klappt es auch auch umgekehrt, also wenn Thread 1 die Datei mit FA2, FS2 öffnet, dann klappt das Öffnen aus Thread 2 auch mit FA1, FS1. Die Reihenfolge spielt so gesehen also keine Rolle.

herbivore

1.361 Beiträge seit 2007
vor 14 Jahren

Warum niemand der msdn vertraut... tse tse 😁Creating and Opening Files

beste Grüße
zommi

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo zommi,

Warum niemand der msdn vertraut...

naja, die Diskussion hier hat sich ja gerade aufgrund einer missverständlichen Formulierung in der MSDN entsponnen ...

herbivore

X
1.177 Beiträge seit 2006
vor 14 Jahren

huhu,

erwähnt sei noch: System.IO.FileShare.None - dadurch darf kein anderer Prozess darauf zugreifen. Dies kann bei Fremdprodukten (Gameserver?) durchaus passieren.

😃

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Xynratron,

ja, stimmt, der Hinweis ist nicht schlecht. Ich hatte in den Test alle FileShare-Modi einbezogen, auch FileShare.None. Nur taucht das nicht in der Liste auf, weil der zweite Thread die Datei dann nicht öffnen kann, egal ob der erste oder der zweite Thread FileShare.None verwendet.

herbivore