Разделить поток памяти на bytarray

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

Кто-нибудь знает, что не так с этим кодом

fb.buffer - это MemoryStream

  long bytesLeft = fb.Buffer.Length;
                fb.Buffer.Position = 0;
                int offset =0;
                int BUFF_SIZE = 8196;


                while (bytesLeft > 0)
                {
                    byte[] fs = new byte[BUFF_SIZE];

                    fb.Buffer.Read(fs, offset, BUFF_SIZE);
                    offset += BUFF_SIZE;
                    bytesLeft -= BUFF_SIZE;
                }

person klashagelqvist    schedule 16.04.2012    source источник
comment
Фактически, вам даже не нужно использовать Read здесь; просто используйте GetBuffer, а затем в цикле Buffer.BlockCopy данные из резервного буфера в меньшие буферы   -  person Marc Gravell    schedule 16.04.2012


Ответы (2)


offset вот смещение в массиве. Здесь должно быть ноль. Вы также должны посмотреть на значение return из Read. Заполнение буфера не гарантируется, даже если доступно больше данных.

Однако, если это MemoryStream, лучшим вариантом может быть ArraySegment<byte>, который не требует дублирования данных.

person Marc Gravell    schedule 16.04.2012
comment
Спасибо, глупая ошибка. Раньше видел это «не гарантировано заполнение буфера» и всегда задавался вопросом, что это значит. Является ли операция чтения случайным процессом или? - person klashagelqvist; 16.04.2012
comment
@klashagelqvist На NetworkStream это в значительной степени так. Если данных еще не поступило для заполнения буфера, но соединение также не было закрыто, он заполнит только часть буфера доступными данными и вернется. Но я не думаю, что такое частичное чтение может происходить с MemoryStream. - person CodesInChaos; 16.04.2012
comment
@klashagelqvist действительно, как отмечает CodeInChaos, MemoryStream, вероятно, не укусит вас здесь, но это деталь реализации. Я настоятельно рекомендую следовать формальному Stream API, который только не гарантирует отсутствие или некоторые - person Marc Gravell; 16.04.2012

Посмотрите этот код для Stream.Read из MSDN с первого взгляда - вы не должны увеличивать offset - он всегда должен быть равен нулю. Если, конечно, вы заранее не знаете точную длину потока (поэтому вы должны создать массив точного размера).

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

Если вы хотите разбить его на «куски», вы имеете в виду, что вам нужно n 8k кусков? Тогда вы можете сделать что-то вроде этого:

List<byte[]> chunks = new List<byte[]>();
byte chunk = new byte[BUFF_SIZE];
int bytesRead = fb.Buffer.Read(chunk, 0, BUFF_SIZE);
while(bytesRead > 0)
{
  if(bytesRead != BUFF_SIZE)
  {
    byte[] tail = new byte[bytesRead];
    Array.Copy(chunk, tail, bytesRead);
    chunk = tail;
  }
  chunks.Add(chunk);
  bytesRead = fb.Buffer.Read(chunk, 0, BUFF_SIZE);
}

Обратите внимание, в частности, что последний кусок, скорее всего, не будет иметь длину точно BUFF_SIZE.

person Andras Zoltan    schedule 16.04.2012