ArgumentOutOfRangeException при чтении байтов из потока

Я пытаюсь прочитать поток ответа от объекта HttpWebResponse. Я знаю длину потока (_response.ContentLength), но получаю следующее исключение:

Указанный аргумент находится вне диапазона допустимых значений. Название параметра: размер

Во время отладки я заметил, что на момент ошибки значения были такими:

length = 15032 // длина потока, как определено _response.ContentLength

bytesToRead = 7680 // количество байтов в потоке, которые еще нужно прочитать

bytesRead = 7680 // количество байтов, которые были прочитаны (смещение)

body.length = 15032 // размер байта [], в который копируется поток

Особенность заключается в том, что переменные bytesToRead и bytesRead ВСЕГДА имеют значение 7680, независимо от размера потока (содержащегося в переменной длины). Любые идеи?

Код:

int length = (int)_response.ContentLength;

byte[] body = null;

if (length > 0)
{
    int bytesToRead = length;
    int bytesRead = 0;

    try
    {
        body = new byte[length];

        using (Stream stream = _response.GetResponseStream())
        {
            while (bytesToRead > 0)
            {                                                        
                // Read may return anything from 0 to length.
                int n = stream.Read(body, bytesRead, length);

                // The end of the file is reached.
                if (n == 0)
                    break;

                bytesRead += n;
                bytesToRead -= n;
            }
            stream.Close();
        }
    }
    catch (Exception exception)
    {
        throw;
    }   
}
else
{
    body = new byte[0];
}

_responseBody = body;

person user345194    schedule 19.05.2010    source источник


Ответы (1)


Вам нужна эта строка:

int n = stream.Read(body, bytesRead, length);

быть таким:

int n = stream.Read(body, bytesRead, bytesToRead);

Вы говорите, что максимальное количество байтов для чтения - это длина потока, но это не так, поскольку на самом деле это только оставшаяся информация в потоке после применения смещения.

Вам также не понадобится эта деталь:

if (n == 0)
   break;

Время должно правильно завершить чтение, и возможно, что вы не прочитаете никаких байтов, пока не закончите все это (если поток заполняется медленнее, чем вы извлекаете из него данные)

person Martin Harris    schedule 19.05.2010
comment
Вы, сэр, гений. Как мне решить вторую проблему (поток заполняется медленнее, чем я его читаю)? Разве установка bytesToRead = length не гарантирует, что все байты потока будут прочитаны? - person user345194; 19.05.2010