Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Размер буфера при сериализации


Автор: Competitor 8.6.2007, 14:46
Привет Всем!
Сериализую объект класса в массив байт:
Код

            byte[] buffer = new byte[4096];
            using (MemoryStream memStream = new MemoryStream(buffer))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(memStream, classObject);
            }


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

Автор: HalkaR 8.6.2007, 14:55
Competitor, естественно если размер обьекта меньще 4K то будет занято меньше.
Если же будет больше, то будет увеличен размер буфера еще на 4К. Такая уж система увеличения буфера по 4К.

Автор: Competitor 8.6.2007, 15:18
HalkaR, ok, перефразирую.
Как решить задачу сериализации объекта в массив байт, чтобы на выходе получился массив именно того размера, который требуется для данного объекта?
Очевидно, что в приведенном мной примере условие этой задачи не выполняются по уже описанным выше причинам.

Автор: Azzdorf 8.6.2007, 16:19
а ты не пробовал просто проводить сериализацию без выделения памяти, Сшарп сам выделит сколько будет нужно

Автор: Competitor 8.6.2007, 16:31
Azzdorf, конечно пробовал. Выдает ошибку: buffer не может быть нулевым.

Автор: tol05 8.6.2007, 16:44
Цитата

MemoryStream()
Инициализирует новый экземпляр класса MemoryStream с помощью расширяемой емкости, инициализированной с нулевым значением.


я так понимаю, тебе при серилизации массив конкретного размера не нужен?

Код

using(MemoryStream memStream = new MemoryStream())
{
   BinaryFormatter formatter = new BinaryFormatter();
   formatter.Serialize(memStream, classObject);
}


Это не из той темы, что мы когда-то обсуждали? smile Я забыл детали уже, так что если что - не бей ногами smile

Автор: Competitor 8.6.2007, 17:21
пять баллов, tol05 smile
Код

            byte[] buffer = null;
            using (MemoryStream memStream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(memStream, employee777);
                buffer = new byte[memStream.Length];
                memStream.Position = 0;
                memStream.Read(buffer, 0, buffer.Length);
            }


ЗЫ: Когда же я наконец научусь сам пользовать гуглем и мсдном :(

Автор: Competitor 8.6.2007, 18:08
А как обыграть ситуацию, когда идет чтение из NetworkStream? Т.е. смысл тот же, после чтения из потока получить массив точно такого же размера, который необходим:
Код

                    this.networkStream = new NetworkStream(this.socket);
                    .....
                    byte[] buffer = new byte[4096];
                    int readBytes = this.networkStream.Read(buffer, 0, buffer.Length);

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

Автор: tol05 8.6.2007, 18:34
Цитата

NetworkStream.Length Property 
Gets the length of the data available on the stream. This property is not currently supported and always throws a NotSupportedException. 


Э, тут никак, по-моему. Для сетевых потоков (и для MemoryStream) нельзя узнать кол-во данных, пока не прочтешь. Сделано это для уменьшения траффика типа smile
http://forum.vingrad.ru/index.php?showtopic=145456&view=findpost&p=1093850

только так: задаешь массив конкретного размера, читаешь в него, пересохраняешь куда-нибудь данные, читаешь снова и так, пока не закончатся данные для чтения. Смотришь перед каждым чтением свойство this.networkStream.DataAvailable когда данных не будет, берешь последнее значение своего readBytes и 
Код

int totalBytes = readBytes + CountOfReads*buffer.Length

 smile 

P.S. Можно сохранять все полученные данные опять же в MemoryStream, а потом из него получить массив всех полученных данных

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)