Подтвердить что ты не робот

Stream.Length выбрасывает NotSupportedException

Я получаю сообщение об ошибке при попытке stream.Length объекта Stream, отправленного в мой метод WCF.

Unhandled Exception!
 Error ID: 0
 Error Code: Unknown
 Is Warning: False
 Type: System.NotSupportedException
 Stack:    at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.get_Length()

Как вы получаете длину потока? любые примеры?

4b9b3361

Ответ 1

Stream.Length работает только с потоковыми реализациями, где поиск доступен. Обычно вы можете проверить, соответствует ли Stream.CanSeek. Многие потоки, поскольку они передаются потоком, имеют природу, где невозможно заранее знать длину.

Если вы знаете длину, вам может понадобиться фактически буферизовать весь поток, предварительно загружая его в память.

Ответ 2

Я столкнулся с этой же проблемой при использовании служб WCF. Мне нужно было получить содержимое сообщения POST, и я использовал аргумент Stream в моем методе, чтобы получить содержимое тела сообщения. Как только я получил поток, мне захотелось прочитать его содержимое сразу, и мне нужно было знать, какой размерный байт я буду нуждаться. Таким образом, при распределении массива я бы назвал System.IO.Stream.Length и получил исключение, указанное OP. Является ли причина, по которой вам нужно знать длину потока, чтобы вы могли прочитать содержимое всего потока? Фактически вы можете прочитать все содержимое потока в строке с помощью System.IO.StreamReader. Если вам все еще нужно знать размер вашего потока, вы можете получить длину результирующей строки. Вот код, как я решил эту проблему:

    [OperationContract]
    [WebInvoke(UriTemplate = "authorization")]
    public Stream authorization(Stream body)
    {
        // Obtain the token from the body
        StreamReader bodyReader = new StreamReader(body);
        string bodyString= bodyReader.ReadToEnd();
        int length=bodyString.Length; // (If you still need this.)
       // Do whatever you want to do with the body contents here. 
    }

Ответ 3

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

Что вы пытаетесь сделать? Не могли бы вы прочитать из потока до исчерпания, скопировав данные в MemoryStream по ходу?

Ответ 4

Не всегда возможно получить длину потока, если он не поддерживает поиск. См. Таблицу исключений в классе Stream.

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

В общем случае вам просто нужно прочитать все данные до конца потока, а затем выяснить, сколько вы прочитали.

Ответ 5

Это то, что я делаю:

    // Return the length of a stream that does not have a usable Length property
    public static long GetStreamLength(Stream stream)
    {
        long originalPosition = 0;
        long totalBytesRead = 0;

        if (stream.CanSeek)
        {
            originalPosition = stream.Position;
            stream.Position = 0;
        }

        try
        {
            byte[] readBuffer = new byte[4096];

            int bytesRead;

            while ((bytesRead = stream.Read(readBuffer, 0, 4096)) > 0)
            {
                totalBytesRead += bytesRead;
            }

        }
        finally
        {
            if (stream.CanSeek)
            {
                stream.Position = originalPosition;
            }
        }

        return totalBytesRead;
    }

Ответ 6

TcpClient.EndRead() должен возвращать количество байтов, находящихся в потоке.

- Редактировать, конечно, вам нужно использовать поток TCP