简体   繁体   English

可观察的 <byte[]> 转换

[英]IObservable<byte[]> conversion

How can I convert IObservable to byte[]? 如何将IObservable转换为byte []?

I want to convert IObservable to a wav file and save it on the disk. 我想将IObservable转换为wav文件并将其保存在磁盘上。

DisOutput d;
File.WriteAllBytes("outputsend.wav", d);

I have an array IObservable which I want to convert to byte[] so that I can write to a file. 我有一个IObservable数组,我想将其转换为byte []以便可以写入文件。 How can I convert IObservable to byte[] because WriteAllBytes takes byte[] as input 我如何将IObservable转换为byte [],因为WriteAllBytes将byte []作为输入

I assume that you have a framework that generates a WAV file on the fly in the form of an IObservable<Byte> . 我假设您有一个以IObservable<Byte>的形式即时生成WAV文件的框架。 Presumably, when the generation is complete the IObservable<Byte> will fire OnCompleted to signal this. 据推测,当生成完成时, IObservable<Byte>将触发OnCompleted发出信号。

IObservable<Byte> observable;

The simplest way to do what you want is to use ToList which will generate an IObservable<IList<Byte>> that fires when the source observable sequence completes: 执行所需操作的最简单方法是使用ToList ,它将生成IObservable<IList<Byte>> ,该源可观察序列完成时将触发该IObservable<IList<Byte>>

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

What happens is that the ToList operator will collect all incoming bytes in a list that grows over time. 发生的事情是ToList运算符将收集列表中所有传入的字节,该列表随着时间的推移而增长。 When the incoming sequence completes the subscribers are notified and in this case the list of bytes is written to a file. 当输入序列完成时,将通知订户,在这种情况下,字节列表将被写入文件。

However, there is no need to buffer the bytes in memory. 但是,无需在内存中缓冲字节。 Instead they can be written directly to the file. 而是可以将它们直接写入文件。 It is important that the file is closed when the incoming stream of bytes completes and this can be achieved using this somewhat more complicated but also more efficient extension method: 重要的是,当输入的字节流完成时关闭文件,这可以使用以下更复杂但也更有效的扩展方法来实现:

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

}

You can use this extension method like this: 您可以使用以下扩展方法:

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

To handle errors you can use another overload of Subscribe : 要处理错误,可以使用Subscribe另一个重载:

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

This will write exceptions to the console. 这会将异常写入控制台。 A more sophisticated approach would be required in a production quality application. 在生产质量应用中,将需要一种更复杂的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM