Frage

Was ist der einfachste Weg, um einen Strom-/Leser-Linie für Linie in C# zu filtern (ähnlich wie SED mitten in einer Pipeline). Ich möchte eine Icalendar -Datei an dday.ical, aber dday.ical sterben, auf "Version: 5.1.1", da sie eine Nummer oder eine Nummer -Semikolon -Nummer (wo die Nummer Ziffern (Punkte Ziffern) ist)? Also das letzte ".". unerwartet).

Ich möchte die Version filtern: Zeile zu etwas harmloses wie "Version: 5.1", damit der Parser nicht stirbt.

Update: OK, hier ist ein Beispiel:

BEGIN:VCALENDAR
PRODID:-//SunONE/Calendar Hosting Server//EN
METHOD:PUBLISH
VERSION:5.1.1
X-NSCP-CALPROPS-LAST-MODIFIED:20011208T005613Z
X-NSCP-CALPROPS-CREATED:20010913T223336Z
X-NSCP-CALPROPS-READ:999
X-NSCP-CALPROPS-WRITE:999

Jetzt mag der Parser nicht "Version: 5.1.1", also möchte ich das durch etwas harmloses wie "Version: 5.1" ersetzen.

Die Parser -Schnittstelle nimmt einen Leser oder einen Stream.

Wie auch immer, ich habe versucht, den Code zu verwenden hier und es funktioniert (neu auf TexTreader auf einer gefilterten Readline).

War es hilfreich?

Lösung

System.io.Stream verwendet das Dekorateure -Muster, sodass es ziemlich einfach ist, Ihre eigenen zu erstellen, was einen zugrunde liegenden Strom umhüllt. Auf diese Weise können Streams wie Cryptostream und Gzipstream jede andere Stream -Instanz einwickeln und seine Lese-/Schreibmethoden effektiv "überschreiben", ohne aus der Klasse, die Sie erweitern möchten, abzuleiten. Sehr flexibles und beliebtes Designmuster, das in der Bande von Four Book beschrieben wird.

Jetzt bin ich mir nicht sicher, ob die API, mit der Sie arbeiten, einen Stream oder einen StreamReader benötigt. Es gibt eine signifikante Unterscheidung zwischen den beiden. Ein Streamreader arbeitet am Text Level und Operationen auf Zeichen/Zeilen. Ein Stream arbeitet auf Binärebene und arbeitet auf Bytes. Mit anderen Worten, von dem StreamReader wird erwartet, dass er die Bytes in Text dekodieren kann, damit der Verbraucher nicht über die Codierung besorgt sein muss. Verwenden Sie einen Stream, wenn die Codierung keine Rolle spielt (z.

Soweit es sich anhört, würde ein Streamreader hier mehr Sinn machen. Wenn die API einen StreamReader akzeptieren kann, leiten Sie einfach Ihre eigene von TexTreader ab und überschreiben seine Readline -Methode, sodass der erste Anruf die Textzeile zurückgibt, die Sie angehängt werden, und nachfolgende Aufrufe nur als normal funktionieren.

Die andere Option besteht darin, nur einen StringWriter/StringReader zu verwenden und alles in einen In-Memory-String-Puffer zu stopfen, ihn zu manipulieren und dann zu übergeben.

Andere Tipps

Der einfachste Weg könnte darin bestehen, den Stream als IEnumerable und Filter mit Linq zu wickeln:

static void Main(string[] args)
{
    System.IO.StreamReader sr = // ...
    var filtered = Enumerable.Where(
        StreamReaderToSeq(sr), input => { int temp; return int.TryParse(x, out temp); });
}

static IEnumerable<string> StreamReaderToSeq(System.IO.StreamReader sr)
{
    while(!sr.EndOfStream)
    {
        yield return sr.ReadLine();
    }
}

Die Sequenz oben filtert nur Ganzzahlen, aber es ist leicht genug, einen besseren Filter zu schreiben, um alle gewünschten Eingänge zu verarbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top