IObservable <byte []>转换

时间:2015-06-24 10:36:55

标签: c#

如何将IObservable转换为byte []?

我想将IObservable转换为wav文件并将其保存在磁盘上。

Sub errors()

Dim Sheet1 As String
Dim mycell As Range
Dim datecol As Long
Dim col As Long

Sheet1 = "different"    

For Each mycell In ActiveWorkbook.Worksheets(shtSheet1).Range("B:B")
    If mycell.Interior.Color = vbRed Then
        datecol = datecol + 1
End If
Next mycell

Debug.Print datecol

End Sub

我有一个数组IObservable,我想将其转换为byte [],以便我可以写入文件。如何将IObservable转换为byte [],因为WriteAllBytes将byte []作为输入

1 个答案:

答案 0 :(得分:2)

我假设您有一个框架,它以IObservable<Byte>的形式动态生成WAV文件。据推测,当生成完成后,IObservable<Byte>将触发OnCompleted发出信号。

IObservable<Byte> observable;

执行所需操作的最简单方法是使用ToList,这将生成在源可观察序列完成时触发的IObservable<IList<Byte>>

observable.ToList().Subscribe(list => File.WriteAllBytes("outputsend.wav", list.ToArray());

会发生的是ToList运算符将收集随时间增长的列表中的所有传入字节。当传入序列完成时,将通知订户,在这种情况下,字节列表将写入文件。

但是,不需要缓冲内存中的字节。相反,它们可以直接写入文件。当传入的字节流完成时,关闭文件是很重要的,这可以使用这种更复杂但更有效的扩展方法来实现:

static class ObservableExtensions {

  public static IObservable<Unit> WriteToFile(this IObservable<Byte> source, String fileName) {
    return Observable.Create<Unit>(
      observer => {
        var fileStream = new SerialDisposable();
        return new CompositeDisposable(
          source.Subscribe(
            value => {
              try {
                if (fileStream.Disposable == null)
                  fileStream.Disposable = File.Create(fileName);
                ((FileStream) fileStream.Disposable).WriteByte(value);
              }
              catch (SystemException ex) {
                observer.OnError(ex);
              }
            },
            observer.OnError,
            () => {
              observer.OnNext(Unit.Default);
              observer.OnCompleted();
            }
          ),
          fileStream
        );
      }
    );
  }

}

您可以像这样使用此扩展方法:

observable.WriteToFile("outputsend.wav").Subscribe(_ => Console.WriteLine("Done"));

要处理错误,您可以使用Subscribe的另一个重载:

observable.WriteToFile("outputsend.wav").Subscribe(
  _ => Console.WriteLine("Done"),
  ex => Console.WriteLine(ex)
);

这会将异常写入控制台。在生产质量应用中需要更复杂的方法。