Как проверить, можно ли изменять размер потока C #? - PullRequest
3 голосов
/ 24 августа 2011

С http://msdn.microsoft.com/en-us/library/system.io.memorystream%28v=VS.90%29.aspx:

Потоки памяти, созданные с помощью байтового массива без знака, обеспечивают поток данных без изменения размера.При использовании байтового массива вы не можете ни добавлять, ни сокращать поток, хотя вы можете изменить существующее содержимое в зависимости от параметров, переданных в конструктор.Пустые потоки памяти имеют изменяемый размер и могут записываться и считываться.

Когда предоставляется ссылка на MemoryStream (или даже просто Stream), как можно проверить, изменяется ли она?

Ситуация возникла при использовании OpenXML SDK, который требует изменения размера передаваемых ему потоков.Я могу обеспечить возможность изменения размера путем глубокого копирования в поток с изменяемым размером. Мне просто интересно, есть ли конкретная причина, по которой библиотека не выдает исключение, когда ей передается неверный параметр (т. Е. Поток неизменяемого размера).

Ответы [ 2 ]

2 голосов
/ 24 августа 2011

Редактировать : приведенное ниже решение не работает для MemoryStreams, которые были созданы с помощью конструктора MemoryStream(byte[], int, int, bool, bool) с последним параметром publiclyVisible, установленным на true.


Согласно MSDN , MemoryStream.GetBuffer выдаст UnauthorizedAccessException, если объект не был создан с «публично видимым буфером».Конструкторы, перечисленные с публично видимыми буферами, удобно отображаются на те же, которые можно изменять.Таким образом, вы можете проверить его размер, проверив 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;
}
2 голосов
/ 24 августа 2011

Вот один довольно уродливый способ, когда вы ловите исключение NotSupportedException при попытке изменить размер.

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