在C#中过滤流/读取器线的最简单方法是什么(有点像将SED放在管道中间)。我想将一个iCalendar文件馈送到dday.ical但dday.ical在“版本:5.1.1”上死亡,因为它想要一个数字或数字的半元号(其中数字是数字(dot digits)?所以最后一个”。意外)。

我想做的是过滤版本:行为“版本:5.1”之类的无害事物,因此解析器不会死。

更新:好的,这是一个示例:

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

现在,dday.ical解析器不喜欢“版本:5.1.1”,因此我想用“版本:5.1”这样的无害的东西代替。

解析器接口带读取器或流。

无论如何,我尝试使用代码 这里 它起作用(在过滤后的读取线上重新完成Textreader)。

有帮助吗?

解决方案

system.io.stream使用装饰器图案,因此可以轻松地创建包裹底层流的自己。这允许诸如cryptostream和gzipstream之类的流来包装任何其他流实例,并有效地“覆盖”其读/写方法,而无需从您要扩展的类中派生。四本书的帮派中描述的非常灵活和流行的设计模式。

现在,我不确定您正在使用的API是否需要流或流读器。两者之间存在显着区别。流读器在 文本 字符/行的级别和操作。流在二进制级别工作并在字节上运行。换句话说,预计流读器能够将字节解码为文本,因此消费者不需要关注编码。编码时使用流无关紧要(例如压缩或加密时),并在使用文本数据时使用StreamReader。

从听起来的样子来看,流读器在这里更有意义。如果API可以接受StreamReader,只需从Textreader中派生您的读取方法,然后覆盖其读取方法,以便第一个呼叫返回您需要附加的文本线,然后随后的调用正常工作。

另一个选项是仅使用StringWriter/StringReader并将其全部塞入内存的字符串缓冲区中,操纵它,然后将其传递。

其他提示

最简单的方法可能是将流以ienumerable和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();
    }
}

上面的序列仅过滤整数,但是它很容易编写更好的过滤器来处理所需的所有输入。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top