How to check if a C# Stream is resizable?
From http://msdn.microsoft.com/en-us/library/system.io.memorystream%28v=VS.90%29.aspx:
Memory streams created with an unsigned byte array provide a non-resizable stream of the data. When using a byte array, you can neither append to nor shrink the stream, although you might be able to modify the existing contents depending on the parameters passed into the constructor. Empty memory streams are resizable, and can be written to and read from.
When provided a reference to a MemoryStream
(or even just a Stream
), how can one check if it's resizable?
The situation arose when using the OpenXML SDK, which requires the streams passed to it be resizable. I can ensure resizability by deep copying开发者_如何学Python to a resizable stream, I'm just wondering if there's a particular reason why the library doesn't throw an exception when a bad parameter is passed to it (i.e. an unresizable stream).
Here's one kinda ugly way were you catch the NotSupportedException when attempting to resize.
public static bool IsResizable(this Stream stream)
{
bool result;
long oldLength = stream.Length;
try
{
stream.SetLength(oldLength + 1);
result = true;
}
catch (NotSupportedException)
{
result = false;
}
if (result)
{
stream.SetLength(oldLength);
}
return result;
}
Edit: the below solution doesn't work for MemoryStreams that were created using the MemoryStream(byte[], int, int, bool, bool)
constructor with the last parameter publiclyVisible
set to true
.
According to MSDN, MemoryStream.GetBuffer
will throw an UnauthorizedAccessException
if the object was not created with a "publicly visible buffer". The constructors listed with publicly visible buffers conveniently map to the sames ones that are resizable. So you could check that it's re sizable by checking GetBuffer
:
public static bool IsResizable(this MemoryStream stream)
{
if (stream == null) throw new ArgumentNullException("stream");
bool resizable;
try
{
stream.GetBuffer();
resizable = true;
}
catch (UnauthorizedAccessException) { resizable = false; }
return resizable;
}
精彩评论