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

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

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

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

Я очень новичок в 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 ]

18 голосов
/ 25 февраля 2009

Возможно, вы захотите посмотреть 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
 }
4 голосов
/ 25 февраля 2009

Вы, вероятно, хотите 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();
3 голосов
/ 25 февраля 2009

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

например.

Array.Copy(srcBuffer, destBuffer, 1024);
0 голосов
/ 25 февраля 2009

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

0 голосов
/ 25 февраля 2009

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

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

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