James Robinson
James Robinson

Reputation: 1263

How should I wrap a MemoryStream to have access to the data that was written to it even after it is closed

I am attempting to use a ThirdParty library to write some data to a MemoryStream so that I can compare the output as part of some unit tests. Unfortunately the Third Party library closes the MemoryStream during execution of it Save() method.

Thus I have the following code:

byte[] expected = LoadExpectedResult("Test1");
using (var memoryStream = new MemoryStream()) {
    ThirdPartyLibrary.Save(memoryStream);
    var result = memoryStream.ToArray();
    ConfirmBinaryBlobsAreSufficentlyEqual(expected, result);
}

Unfortunately it appears that the memoryStream.ToArray() function is only returning the last 3398 bytes that were the last loaded into the buffer as it has been disposed as part of the save process.

Is there anything I can wrap the MemoryStream in so that as data is written to it, it gets read out or written to another memory stream so that when it is disposed of I can still have access to the data.

Update

For clarity the Save() method also does the writing out so before it is called the MemoryStream is empty. I think the writers of the library expected you to only pass in FileStreams.

Upvotes: 0

Views: 518

Answers (2)

xanatos
xanatos

Reputation: 111870

You can try with:

public class MyMemoryStream : MemoryStream
{
    public bool CanDispose { get; set; }

    public override void Close()
    {
        if (!CanDispose)
        {
            return;
        }

        base.Close();
    }
}

In the Stream class, the Dispose() calls Close() that then calls Dispose(bool disposing). Close() is virtual, so I overrode it.

After using the stream, set CanDispose = true and then let it be disposed normally.

byte[] expected = LoadExpectedResult("Test1");
using (var memoryStream = new MyMemoryStream()) {
    // implicitly memoryStream.CanDispose == false;
    ThirdPartyLibrary.Save(memoryStream);
    var result = memoryStream.ToArray();
    ConfirmBinaryBlobsAreSufficentlyEqual(expected, result);
    memoryStream.CanDispose = true;
}

Upvotes: 2

Michael Kreich
Michael Kreich

Reputation: 175

To circumvent the bug/behaviour: you could either copy the memorystream to a second instance or write it to some temp-file before calling ThirdPartyLibrary.Save.

Upvotes: 0

Related Questions