Pergunta

Qual é a maneira mais fácil de filtrar uma linha por linha a linha em linha C# (como colocar o Sed no meio de um pipeline). Eu quero alimentar um arquivo iCalendar para dday.ical, mas dday.ical. inesperado).

O que eu quero fazer é filtrar a versão: linha para algo inofensivo como "versão: 5.1" para que o analisador não morra.

ATUALIZAÇÃO: OK, aqui está uma amostra:

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

Agora, o analisador DDay.ical não gosta de "versão: 5.1.1", então quero substituir isso por algo inofensivo como "versão: 5.1".

A interface do analisador leva um leitor ou um fluxo.

Enfim, tentei usar o código aqui E funciona (reimplementando o Textader sobre uma linha de leitura filtrada).

Foi útil?

Solução

O System.io.stream usa o padrão do decorador, para facilitar a criação do seu próprio que envolve um fluxo subjacente. Isso permite que fluxos como o CryptoStream e o GzipStream envolvam qualquer outra instância do fluxo e efetivamente "substituam" seus métodos de leitura/gravação sem derivar da classe que você deseja estender. Padrão de design muito flexível e popular descrito na gangue de quatro livros.

Agora não tenho certeza se a API com a qual você está trabalhando exige um fluxo ou streamader. Há uma distinção significativa entre os dois. Um leitor de fluxo funciona no texto Nível e operações em caracteres/linhas. Um fluxo funciona no nível binário e opera em bytes. Em outras palavras, espera -se que o fluxo de fluxo seja capaz de decodificar os bytes em texto para que o consumidor não precise se preocupar com a codificação. Use um fluxo quando a codificação não importa (como quando a compactação ou o fechamento) e use um fluxo de fluxo ao trabalhar com dados de texto.

Pelo que parece, um streamader faria mais sentido aqui. Se a API puder aceitar um fluxo de fluxo, basta derivar o seu próprio do Textreader e substituir seu método ReadLine, para que a primeira chamada retorne a linha de texto que você precisa anexar e subsequente chamadas apenas funcionam normalmente.

A outra opção é usar apenas um StringWriter/StringReader e encher tudo em um buffer de string na memória, manipulá-lo e depois passá-lo.

Outras dicas

A maneira mais fácil pode ser embrulhar o fluxo como um ienumerable e filtrar com 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();
    }
}

A sequência acima dos filtros apenas números inteiros, mas é fácil o suficiente para escrever um filtro melhor para lidar com todas as entradas que você deseja.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top