Frage

Ich habe eine Log-Datei, die von einer dritten Partei Anwendung geschrieben wird, und ich würde meine Bewerbung zu „lesen“, dass die Protokolldatei in real / Neartime mögen, analysieren die neuen Protokolleinträge und wirken auf bestimmte Ereignisse.

Mein Gedanke war, dass ich dies mit einer Kombination von Filesystemwatcher (um Signaldateiänderungen) erreichen könnte und MemoryMappedFile (weiterhin von einem bestimmten Lese Offset).

Da jedoch ist dies das erste Mal, dass ich bin mit MemoryMappedFiles ich in einige Probleme laufen haben, die wahrscheinlich entstehen aus nicht das Konzept richtig zu verstehen (zB ich bin nicht in der Lage, die vorhandene Datei zu öffnen, wie es durch den anderen Prozess verwendet ist ).

Ich habe mich gefragt, ob jemand ein Beispiel hat, wie MemoryMappedFiles zu verwenden, um eine Datei zu lesen, die von einem anderen Prozess gesperrt ist?

Danke,

Tom

EDIT:

Aus den Kommentaren, es sieht aus wie Memory Mapped Files wird mir helfen, nicht auf Dateien zugreifen, die eine exklusive Sperre haben. Doch „Schwanz“ Werkzeuge wie z.B. BareTail (http://www.baremetalsoft.com/baretail/index.php) ist in der Lage, genau das zu tun. Es hat kein Problem, das Lesen der Datei, die eine exklusive Sperre aus einer anderen Anwendung in 1s Intervallen hat). So hat es eine Möglichkeit, dies zu tun?

editEdit :

Um meine eigene Frage, den Trick beantworten in eine gesperrte Datei zu öffnen ist, das Filestream mit den folgenden Zugriffsflags zu erstellen:

fileStream = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite);
War es hilfreich?

Lösung

Um meine eigene Frage, den Trick beantworten in eine gesperrte Datei zu lesen ist das Filestream mit den folgenden Zugriffsflags zu erstellen:

FileStream fileStream = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite);

Jetzt ist es nur eine Frage der beiden zu tun Intervalls Abfrage oder auf der Suche nach Filesystemwatcher Änderungsereignisse Dateiänderungen zu erkennen

Andere Tipps

Ich bin nicht sicher, ob MemoryMappedFiles gehen, Ihnen zu helfen. Werfen Sie einen Blick auf Filestream:

var stream = new FileStream(path, FileMode.Open, FileShare.Read);
stream.Seek(offset, SeekOrigin.Begin);

Obwohl, wenn die 3rd-Party-Anwendung die Datei exklusiv gesperrt hat, gibt es nicht viel, dass man dagegen tun kann ...

[Begin 2. EDIT]

Eine weitere Idee ...

Wenn der Dritte App ein Logging-Framework wie NLog zu verwenden, geschieht, log4net oder System.Diagnostics, können Sie immer noch Ihre eigene Ziel / Appender / Tracelistener und Route schreiben die Nachrichten irgendwo, dass man sie (wie eine aussehen könnte Datei, die ausschließlich nicht geöffnet wird, an einem anderen Prozess, etc).

Wenn Sie Ihre Dritte App ein Logging-Framework verwendet, wir wahrscheinlich über sie jetzt gehört hätte; -)

[Ende 2. EDIT]

[Begin EDIT]

Ich denke, dass ich die Frage falsch verstanden. Es klang zunächst wie Sie einen Dritten Bibliothek wurden, die umgesetzt hatte die Protokollierung und Sie wollten diese Analyse tun, aus dem Programm, das die Protokollierung wurde generiert. Lesen Sie noch einmal Ihre Frage zu haben, es klingt wie Sie von außerhalb der Anwendung in die Protokolldatei zu „hören“ wollen. Wenn das der Fall ist, wahrscheinlich meine Antwort wird dir nicht helfen. Es tut uns Leid.

[Ende EDIT]

Ich habe nichts zu bieten über MemoryMappedFiles, aber ich frage mich, ob Sie erreichen könnten, was Sie nach durch einen benutzerdefinierten Hörer / target / appender für das 3rd-Party-Logging-System zu schreiben?

Zum Beispiel, wenn Sie NLog verwenden, können Sie ein benutzerdefiniertes Ziel schreiben und alle Ihrer Log-Meldungen dort direkt (aber auch sie zu dem „echten“ Target (s lenken)). Auf diese Weise kann Riss an jedem Log-Nachricht erhalten, wie es angemeldet ist (so ist es tatsächlich in Echtzeit, nicht in der Nähe von Echtzeit ist). Sie könnten das gleiche tun mit log4net und System.Diagnostics.

Beachten Sie, dass NLog sogar ein „method“ Ziel hat. Um sicherzustellen, dass man verwenden müssen Sie nur eine statische Methode mit der korrekten Signatur schreiben. Ich weiß nicht, ob log4net ein ähnliches Konzept dazu hat.

Dies scheint, wie es wäre einfacher, arbeitet zuverlässig zu bekommen als zu versuchen, die Protokolldatei zu lesen und zu analysieren, wie es durch die Software von Dritten geschrieben wird.

Wenn die Datei „in Gebrauch“ ist, gibt es nichts, was dagegen getan werden kann. Es ist wirklich „in Gebrauch“. MemoryMappedFiles sind entweder für große Datenmengen aus dem Laufwerk zu lesen oder Daten mit anderen Programmen zu teilen. Es wird nicht helfen, um immer die „in Gebrauch“ Begrenzung.

Memorymapped-Dateien sind unter den gleichen Einschränkungen wie die Filestream Sie es mit initialisieren, stellen Sie sicher, dass Sie Ihre Memory-Mapped-Datei wie folgt initialisieren

var readerStream = new Filestream (Pfad, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

var mmf = MemoryMappedFile.CreateFromFile (readerStream, null, 0, MemoryMappedFileAccess.Read, null, HandleInheritability.None, false);

Wenn ein anderer Prozess es vollständig gesperrt hat sogar vom Schreiben Sie in Pech sind, nicht sicher, ob es eine Möglichkeit, um das. Vielleicht einige Timer Verwenden Sie erkennen, wenn der Prozess schriftlich es zum Stillstand gekommen ist.

Ich habe auf einer Konsole zur Überwachung von Protokolldateien etwas ähnliches gerade getan (wie die Verarbeitung im Gegensatz), aber die Prinzipien sind die gleichen. Wie Sie, verwende ich einen Filesystemwatcher, und die wichtige Logik ist in meinem OnChanged Ereignishandler:

case WatcherChangeTypes.Changed:
{
    System.IO.FileInfo fi = new FileInfo(e.FullPath);

    long prevLength;

    if (lastPositions.TryGetValue(e.FullPath, out prevLength))
    {
        using (System.IO.FileStream fs = new FileStream(
           e.FullPath, FileMode.Open, FileAccess.Read))
        {
            fs.Seek(prevLength, SeekOrigin.Begin);
            DumpNewData(fs, (int)(fi.Length - prevLength));
            lastPositions[e.FullPath] = fs.Position;
        }
    }
    else
      lastPositions.Add(e.FullPath, fi.Length);

    break;
}

Dabei gilt lastPositions ist

Dictionary<string, Int64> lastPositions = new Dictionary<string, long>();

und DumpNewData ist einfach

private static void DumpNewData(FileStream fs, int bytesToRead)
{
    byte[] bytesRead = new byte[bytesToRead];
    fs.Read(bytesRead, 0, bytesToRead);
    string s = System.Text.ASCIIEncoding.ASCII.GetString(bytesRead);
    Console.Write(s);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top