2017-09-27 90 views
1

我有DataWriter已經連接了文件存儲流。在特定的情況下,如何首先在內存中寫入數據,這樣我就可以知道字節的大小,並在作者中存儲數據的大小。如何從MemoryStream寫入DataWriter到磁盤

我該怎麼做,而不是在內存緩衝區中創建兩個?你可以看到我使用兩個緩衝區,一個用於內存流,另一個用於緩衝區,另一個是ibuffer。

我不知道如何直接將inMemory內容寫入DataWriter,它已經連接了filestorage流。

+2

如果你有一個隨機存取(可查找)流,標記的位置,寫的長度爲0,直接寫字節流中,然後覆蓋用正確的值長,一旦你知道了多少字節書面。注意:我對UWP和'DataWriter'一無所知,這就是你一般的做法。 –

+0

@JeroenMostert DataWriter沒有seek方法。基礎流支持隨機訪問和尋找。但datawriter是包裝,所以我沒有直接訪問基礎流。 DataWriter是順序編寫器,它提供了易於使用的方法將數據寫入流(如BinaryWriter)。它有自己的緩衝區,可能會或可能不會將緩衝區提交到基礎流中,所以我想這就是爲什麼不支持搜索。 –

回答

0

我不得不寫我自己的緩衝流,以防止重複的緩衝區創建。雖然流緩衝區內部像列表一樣工作,但當列表變大時它有好處。

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

然後我可以很容易地做到這一點。

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

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