Нужен цикл для копирования фрагментов из байтового массива

Мне нужно обработать большой массив байтов, который передается моей функции. Мне нужно скопировать содержимое из этого массива входящих байтов меньшими «кусками» в массив исходящих байтов.

Для каждого «фрагмента» данных, созданного в исходящем массиве, мне нужно вызвать веб-службу.

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

Я очень новичок в C#, и я борюсь с работающим циклом. Я знаю, как вызвать веб-службу для обработки «фрагмента», но не могу правильно определить цикл. Вот набросок того жалкого беспорядка, который у меня сейчас есть:

int chunkSize = 10000;
byte[] outboundBuffer = new byte[chunkSize];     
while (BytesRead > 0)
{
long i = 0;
foreach (byte x in incomingArray)
{
    BytesRead += 1;
    outboundBuffer[i] = incomingArray[i]
    i++;
}
uploadObject.Size = BytesRead;
uploadObject.MTOMPayload = outboundBuffer;

// call web service here and pass the uploadObject 

// get next "chunk" until incomingArray is fully processed 
 }

Я знаю, что это беспорядок и не сработает; может кто-нибудь набросать правильный цикл, чтобы это сделать? Спасибо большое.

Ответов (5)

Решение

Возможно, вы захотите изучить Array.Copy или Buffer.BlockCopy ; это немного очистит ситуацию, поскольку вам не придется копировать все байты по отдельности:

int incomingOffset = 0;

while(incomingOffset < incomingArray.Length)
{
   int length = 
      Math.Min(outboundBuffer.Length, incomingArray.Length - incomingOffset);

   // Changed from Array.Copy as per Marc's suggestion
   Buffer.BlockCopy(incomingArray, incomingOffset, 
                    outboundBuffer, 0, 
                    length);

   incomingOffset += length;

   // Transmit outbound buffer
 }

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

Псевдокод может выглядеть примерно так:

while (there are chunks in incoming array)
    copy 1 chunk to outbound array
    create uploadObject
    call webservice
endwhile

Почему бы просто не использовать Array.Copy? http://msdn.microsoft.com/en-us/library/system.array.copy.aspx

например.

Array.Copy(srcBuffer, destBuffer, 1024);

Остерегайтесь синхронного вызова веб-сервисов в цикле. Синхронные вызовы веб-сервисов занимают неопределенное время из-за природы HTTP, и ваш цикл может работать долгое время. Предпочтительно использовать асинхронный подход.

Вы, вероятно, захотите Buffer.BlockCopy (самая сырая из копий; идеально подходит для byte[] ).

Конечно, другой вариант - использовать MemoryStream вместо исходящего массива, и Write каждый раз только к нему, а затем вызывать ToArray() или GetBuffer() на MemoryStreamGetBuffer(), вам нужно следить за длиной; с ToArray() ней она обрезается для вас автоматически):

MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesReceived;
while((bytesReceived = GetNextChunk(buffer, 0, BUFFER_SIZE)) > 0) {
    ms.Write(incomingArray, 0, bytesReceived);
}
byte[] final = ms.ToArray();