结合Stream的部分

时间:2015-01-22 09:50:47

标签: system.reactive rx-java

我有一个观察者正在观看不断写入的日志。每一行都是一个新的onNext调用。有时,日志会在多行上输出单个日志项。检测到这很容易,我找不到合适的RX呼叫。

我想找到一种方法将单个日志项目收集到行列表中,并在单个日志项目完成时单击列表。

Buffer似乎不正确,因为这不是基于时间的,它是基于算法的。

GroupBy可能是我想要的,但文档令人困惑。似乎它创建的可观察量可能不会在源可观察源完成之前调用onComplete。

此解决方案不能延迟日志(最好不要延迟)。我需要尽可能接近实时阅读日志,并且订购事宜。

任何向正确方向的推动都会很棒。

1 个答案:

答案 0 :(得分:0)

这是典型的反应性解析问题。您可以使用Rxx Parsers,或者对于本机解决方案,您可以使用Scan或通过定义async iterator来构建自己的状态机。 Scan适用于简单的解析器,并且通常使用Scan-Where-Select模式。

异步迭代器状态机示例:Turnstile

Scan解析器示例(未经测试):

IObservable<string> lines = ReadLines();
IObservable<IReadOnlyList<string>> parsed = lines.Scan(
  new
  {
    ParsingItem = (IEnumerable<string>)null,
    Item = (IEnumerable<string>)null
  },
  (state, line) =>
    // I'm assuming here that items never span lines partially.
    IsItem(line)
    ? IsItemLastLine(line)
      ? new
        {
          ParsingItem = (IEnumerable<string>)null,
          Item = (state.ParsingItem ?? Enumerable.Empty<string>()).Concat(line)
        }
      : new
        {
          ParsingItem = (state.ParsingItem ?? Enumerable.Empty<string>()).Concat(line),
          Item = (List<string>)null
        }
    : new
      {
        ParsingItem = (IEnumerable<string>)null,
        Item = new[] { line }
      })
  .Where(result => result.Item != null)
  .Select(result => result.Item.ToList().AsReadOnly());