Чтение из потока, не зная, сколько ожидать [c #] - PullRequest
1 голос
/ 07 мая 2009

Как я могу прочитать из потока, когда я не знаю заранее, сколько данных поступит? Прямо сейчас я выбрал число на верхней стороне (как в коде ниже), но нет никакой гарантии, что я не получу больше.

Итак, я читаю байт за раз в цикле, каждый раз меняя размер массива? Похоже, слишком большое изменение размера, чтобы быть сделано: - /

TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(ip, port);

Stream stm = tcpclnt.GetStream();

stm.Write(cmdBuffer, 0, cmdBuffer.Length);

byte[] response = new Byte[2048];
int read = stm.Read(response, 0, 2048);

tcpclnt.Close();

Ответы [ 6 ]

6 голосов
/ 07 мая 2009

MemoryStream - твой друг

http://msdn.microsoft.com/en-us/library/system.io.memorystream

Создайте без размера по умолчанию, и он будет автоматически изменен. Затем просто выполните цикл, предлагая каждый раз читать разумное количество данных. Я обычно выбираю как минимум MTU в качестве размера буфера по умолчанию.

Чтобы получить базовый массив byte [], который он создает, вызовите

memoryStreamInstance.GetBuffer() 
3 голосов
/ 07 мая 2009

Вы пробовали класс StreamReader? Я не уверен, применимо ли это к этому случаю, но я использовал StreamReader для чтения потоков ответов HttpWebResponse в прошлом. Очень прост в использовании.

StreamReader reader = new StreamReader(stm);
String result = reader.ReadToEnd();
3 голосов
/ 07 мая 2009

Собираем все вместе, предполагая, что вы не получите ОГРОМНОЕ (больше, чем может поместиться в памяти) количество данных:

TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(ip, port);
Stream stm = tcpclnt.GetStream();
stm.Write(cmdBuffer, 0, cmdBuffer.Length);
MemoryStream ms = new MemoryStream();
byte[] buffer = new Byte[2048];
int length;
while ((length = stm.Read(buffer, 0, buffer.Length)) > 0)
    ms.Write(buffer, 0, length);
tcpclnt.Close();
byte[] response = ms.ToArray();

Как уже упоминалось, MemoryStream будет обрабатывать динамическое распределение байтов для вас. И Stream.Read(byte[], int, int) вернет длину байтов, найденных в этом «чтении», или 0, если достигнут конец.

1 голос
/ 07 мая 2009
int count;
while ( (count = stm.Read(buffer, 0, buffer.Length)) > 0 ) {
   // process buffer[0..count-1]
   // sample:
   // memoryStream.Write(buffer, 0, count);
}
0 голосов
/ 07 мая 2009

Полагаю, это зависит от того, что вы собираетесь делать с данными?

Если вам все это не нужно сразу, вы можете просто выполнить операцию чтения внутри цикла?

0 голосов
/ 07 мая 2009

Код:

byte[] buffer = new byte[1024];
int amt = 0;
while((amt = stm.Read(buffer, 0, 1024) != 0)
{
   // do something
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...