如何在C#中实现IRandomAccessStream?

时间:2012-12-05 12:33:35

标签: c# streaming windows-runtime

我想在C#中实现IRandomAccessStream的实例(它将返回实时生成的数据)。该流实际上不需要是可写的或可搜索的,但我想在ReadAsync方法(实际上是IInputStream的一部分)中返回我自己的数据。

public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
{
    throw new NotImplementedException("To be done");
}

我的两个主要问题是:

  1. 如何返回实现IAsyncOperationWithProgress的内容?框架中是否有任何内容可以帮助解决这个问题?
  2. 如何将数据写入缓冲区? IBuffer只有LengthCapacity属性(具体的Buffer类不再提供)。

2 个答案:

答案 0 :(得分:4)

How to Convert byte Array to IRandomAccessStream

我发现这篇博客文章,希望IRandomAccessStream的这种实现可以成为你的起点。

class MemoryRandomAccessStream : IRandomAccessStream
{
    private Stream m_InternalStream;

    public MemoryRandomAccessStream(Stream stream)
    {
        this.m_InternalStream = stream;
    }

    public MemoryRandomAccessStream(byte[] bytes)
    {
        this.m_InternalStream = new MemoryStream(bytes);
    }

    public IInputStream GetInputStreamAt(ulong position)
    {
        this.m_InternalStream.Seek((long)position, SeekOrigin.Begin);

        return this.m_InternalStream.AsInputStream();
    }

    public IOutputStream GetOutputStreamAt(ulong position)
    {
        this.m_InternalStream.Seek((long)position, SeekOrigin.Begin);

        return this.m_InternalStream.AsOutputStream();
    }

    public ulong Size
    {
        get { return (ulong)this.m_InternalStream.Length; }
        set { this.m_InternalStream.SetLength((long)value); }
    }

    public bool CanRead
    {
        get { return true; }
    }

    public bool CanWrite
    {
        get { return true; }
    }

    public IRandomAccessStream CloneStream()
    {
        throw new NotSupportedException();
    }

    public ulong Position
    {
        get { return (ulong)this.m_InternalStream.Position; }
    }

    public void Seek(ulong position)
    {
        this.m_InternalStream.Seek((long)position, 0);
    }

    public void Dispose()
    {
        this.m_InternalStream.Dispose();
    }

    public Windows.Foundation.IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
    {
        var inputStream = this.GetInputStreamAt(0);
        return inputStream.ReadAsync(buffer, count, options);
    }

    public Windows.Foundation.IAsyncOperation<bool> FlushAsync()
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.FlushAsync();
    }

    public Windows.Foundation.IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.WriteAsync(buffer);
     }
}

答案 1 :(得分:1)

  1. 使用AsyncInfo.Run(Func<CancellationToken, IProgress<uint>, Task<IBuffer>>)方法从委托创建IAsyncOperationWithProgress实例。

    public IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
    {    
        if (buffer == null) throw new ArgumentNullException("buffer");
    
        Func<CancellationToken, IProgress<uint>, Task<IBuffer>> taskProvider =
        (token, progress) => ReadBytesAsync(buffer, count, token, progress, options);
    
        return AsyncInfo.Run(taskProvider);
    }
    
    private async Task<IBuffer> ReadBytesAsync(IBuffer buffer, uint count, CancellationToken token, IProgress<uint> progress, InputStreamOptions options)
    {
    ... Fill the buffer here. Report the progress.
        return buffer;
    }
    
  2. 通常您不需要直接访问缓冲区数据。但是如果您需要在c#中执行此操作,则可以使用System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions类将数据复制到缓冲区中。