Question

Quelle est la façon la plus simple de filtrer un flux / lecteur ligne par ligne en C # (comme mettre SED au milieu d'un pipeline). Je veux nourrir un fichier icalEndar à Dday.ical mais Dday.ical meurt sur "Version: 5.1.1" car il veut un numéro ou un numéro de numéro (où le numéro est des chiffres (chiffres à points)? Donc le dernier "." Est inattendu).

Ce que je veux faire, c'est filtrer la version: Ligne vers quelque chose d'inoffensive comme "Version: 5.1" afin que l'analyseur ne meure pas.

MISE À JOUR: OK, voici un échantillon:

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

Maintenant, l'analyseur Dday.ical n'aime pas "Version: 5.1.1", donc je veux le remplacer par quelque chose d'inoffensive comme "Version: 5.1".

L'interface de l'analyseur prend un lecteur ou un flux.

Quoi qu'il en soit, j'ai essayé d'utiliser le code ici Et cela fonctionne (réimplémentation de TexTreader en plus d'une ligne de lecture filtrée).

Était-ce utile?

La solution

System.io.Stream utilise le motif du décorateur afin qu'il soit assez facile de créer le vôtre qui enveloppe un flux sous-jacent. Cela permet aux flux tels que CryptoStream et GZIPStream pour envelopper toute autre instance de flux et «remplacer efficacement» ses méthodes de lecture / écriture sans dériver de la classe que vous souhaitez étendre. Modèle de conception très flexible et populaire décrit dans le livre Gang of Four.

Maintenant, je ne sais pas si l'API avec laquelle vous travaillez nécessite un flux ou un leader. Il existe une distinction significative entre les deux. Un lecteur de stream fonctionne au texte Niveau et opérations sur les caractères / lignes. Un flux fonctionne au niveau binaire et opère sur des octets. En d'autres termes, le lecteur de stream devrait être en mesure de décoder les octets en texte afin que le consommateur n'ait pas besoin de se préoccuper de l'encodage. Utilisez un flux lorsque le codage n'a pas d'importance (comme lors de la compression ou de l'enceinte) et utilisez un lecteur de stream lorsque vous travaillez avec des données de texte.

D'après ce à quoi cela ressemble, un lecteur de stream aurait plus de sens ici. Si l'API peut accepter un lecteur de stream, il suffit de dériver le vôtre de TexTreader et de remplacer sa méthode de lecture afin que le premier appel renvoie la ligne de texte dont vous avez besoin et les appels ultérieurs fonctionnent comme normaux.

L'autre option consiste à utiliser simplement un stringwriter / stringReader et à tout fourrer dans un tampon de chaîne en mémoire, à le manipuler, puis à le passer.

Autres conseils

Le moyen le plus simple pourrait être d'envelopper le flux comme un ienuable et de filtrer avec Linq:

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();
    }
}

La séquence ci-dessus ne filtre que les entiers, mais il est assez facile d'écrire un meilleur filtre pour gérer toutes les entrées que vous souhaitez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top