7

ストリームにデータを追加しようとしています。これは、でうまく機能しますが、バッファサイズが固定されているためではFileStreamありません。MemoryStream

ストリームにデータを書き込む方法は、ストリームを作成する方法とは別のものです(以下の例では大幅に簡略化しています)。ストリームを作成するメソッドは、ストリームに書き込まれるデータの長さを認識しません。

public void Foo(){
    byte[] existingData = System.Text.Encoding.UTF8.GetBytes("foo");
    Stream s1 = new FileStream("someFile.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
    s1.Write(existingData, 0, existingData.Length);


    Stream s2 = new MemoryStream(existingData, 0, existingData.Length, true);
    s2.Seek(0, SeekOrigin.End); //move to end of the stream for appending

    WriteUnknownDataToStream(s1);
    WriteUnknownDataToStream(s2); // NotSupportedException is thrown as the MemoryStream is not expandable
}

public static void WriteUnknownDataToStream(Stream s)
{
   // this is some example data for this SO query - the real data is generated elsewhere and is of a variable, and often large, size.
   byte[] newBytesToWrite = System.Text.Encoding.UTF8.GetBytes("bar"); // the length of this is not known before the stream is created.
   s.Write(newBytesToWrite, 0, newBytesToWrite.Length);
}

私が持っていたアイデアは、拡張可能MemoryStream関数を関数に送信してから、返されたデータを既存のデータに追加することでした。

public void ModifiedFoo()
{
   byte[] existingData = System.Text.Encoding.UTF8.GetBytes("foo");
   Stream s2 = new MemoryStream(); // expandable capacity memory stream

   WriteUnknownDataToStream(s2);

   // append the data which has been written into s2 to the existingData
   byte[] buffer = new byte[existingData.Length + s2.Length];
   Buffer.BlockCopy(existingData, 0, buffer, 0, existingData.Length);
   Stream merger = new MemoryStream(buffer, true);
   merger.Seek(existingData.Length, SeekOrigin.Begin);
   s2.CopyTo(merger);
}

より良い(より効率的な)ソリューションはありますか?

4

1 に答える 1

27

考えられる解決策は、そもそもの容量を制限しないことMemoryStreamです。書き込む必要のある合計バイト数が事前にわからない場合は、MemoryStream容量を指定せずにを作成し、両方の書き込みに使用します。

byte[] existingData = System.Text.Encoding.UTF8.GetBytes("foo");
MemoryStream ms = new MemoryStream();
ms.Write(existingData, 0, existingData.Length); 
WriteUnknownData(ms);

MemoryStreamこれは、からaを初期化するよりもパフォーマンスが低下することは間違いありませんがbyte[]、ストリームへの書き込みを続行する必要がある場合は、それが唯一の選択肢であると思います。

于 2012-09-09T14:53:28.200 に答える