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
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!!! 😁
==============================
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!"
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.
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!"
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?
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!"
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
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!"
Schade... Die Fehlermeldung tritt weiterhin auf 😦
Trotzdem vielen Dank für deine Hilfe. Falls jemand doch noch eine Idee hat - bitte schreiben 😃
cocacola
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!"
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.
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!"
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.
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 😉 )
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.
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
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
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.
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