简体   繁体   English

如何从MemoryStream写入DataWriter到磁盘

[英]How to write from MemoryStream into DataWriter into disk

I have DataWriter that has file storage stream already attached. 我有已附加文件存储流的DataWriter。 how ever in particular case I want to first write data in memory so I can know size of bytes, and store size with data in writer. 我想如何在特定情况下首先将数据写入内存,以便我可以知道字节的大小,并在写入器中存储数据的大小。

How can I do that without creating two in memory buffers? 如何在不创建两个内存缓冲区的情况下做到这一点?

DataWriter writer; // writer is parameter passed from somewhere else.

using (var inMemory = new InMemoryRandomAccessStream())
{
    // fill inMemory with data.

    // ***Here*** How can I avoid this?
    var buffer = new byte[checked((int)inMemory.Position)].AsBuffer();

    inMemory.Seek(0);
    await inMemory.ReadAsync(buffer, buffer.Length, InputStreamOptions.ReadAhead);

    writer.WriteUInt32(buffer.Length); // write size
    writer.WriteBuffer(buffer); // write data
}

As you can see I'm using two buffers, one is for memory stream, the other is ibuffer. 如您所见,我正在使用两个缓冲区,一个用于内存流,另一个用于ibuffer。

I don't know how to directly write inMemory contents into DataWriter which has filestorage stream already attached. 我不知道如何直接将inMemory内容写入已经附加了文件存储流的DataWriter中。

I had to write my own buffer stream in order to prevent duplicate buffer creation. 我必须编写自己的缓冲区流,以防止创建重复的缓冲区。 though stream buffer internally works like list but it has benefits when list grows large. 尽管流缓冲区在内部像list一样工作,但是当list变大时,它有好处。

internal sealed class BufferStream : IDisposable
{
    private byte[] _array = Array.Empty<byte>();
    private int _index = -1;
    private const int MaxArrayLength = 0X7FEFFFFF;

    public int Capacity => _array.Length;
    public int Length => _index + 1;

    public void WriteIntoDataWriterStreamAsync(IDataWriter writer)
    {
        // AsBuffer wont cause copy, its just wrapper around array.
        if(_index >= 0) writer.WriteBuffer(_array.AsBuffer(0, _index)); 
    }

    public void WriteBuffer(IBuffer buffer)
    {
        EnsureSize(checked((int) buffer.Length));

        for (uint i = 0; i < buffer.Length; i++)
        {
            _array[++_index] = buffer.GetByte(i);
        }
    }

    public void Flush()
    {
        Array.Clear(_array, 0, _index);
        _index = -1;
    }

    // list like resizing.
    private void EnsureSize(int additionSize)
    {
        var min = additionSize + _index;
        if (_array.Length <= min)
        {
            var newsize = (int) Math.Min((uint) _array.Length * 2, MaxArrayLength);
            if (newsize <= min) newsize = min + 1;
            Array.Resize(ref _array, newsize);
        }
    }

    public void Dispose()
    {
        _array = null;
    }
}

Then I can easily do this. 然后,我可以轻松地做到这一点。

using (var buffer = new BufferStream())
{
    // fill buffer

    writer.WriteInt32(buffer.Length); // write size
    buffer.WriteIntoDataWriterStream(writer); // write data
}

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

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