2013-08-22 1 views
0

Я хочу спросить о сериализации/десериализации объекта с бинарным форматированием. ну, я пытаюсь десериализовать объект в FileStream, который содержит много объектов, которые были сериализованы один за другим. Размер объекта слишком велик, чтобы быть сохраненным в памяти процессов, поэтому я не собираю все объекты в одном, например: Список, потому что они слишком большие в памяти процесса. Поэтому я сериализую столько, сколько необходимо во много раз , таким образом, это не займет много памяти процессов, потому что я просто обрабатываю один объект поочередно не всеми объектами. взгляните на эскизе, что я имею в видуBinary Formatter, Установить позицию для десериализации конкретного объекта

<FileStream> 
----Object 1-----Size = 100 Mb------index = 0 
----Object 2-----Size = 100 Mb------index = 1 
----Object 3-----Size = 100 Mb------index = 2 
----Object 4-----Size = 100 Mb------index = 3 
----Object 5-----Size = 100 Mb------index = 4 
----Object 6-----Size = 100 Mb------index = 5 
</FileStream> 

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

List<object> list = new List<object>(); 
    list(0) = "object1"; 
    list(1) = "object2"; 
    list(2) = "object3"; 
    list(3) = "object4"; 
    list(4) = "object5"; 
    list(5) = "object6"; 
    object fifthIndex = list[5]; // here we can get item based index 

Ну теперь проблема в том, как я могу получить объекты с пятым индексом так же, как Список Method на шесть объекте десериализации в FileStream с бинарным форматированием. я знаю, что в FileStream есть свойство, которое называется FileStream.Position, но оно не похоже на Index, оно выглядит как случайное число, когда я десериализую/сериализую объект. возможно, это увеличит случайное число.

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

object GetObjectStream(FileStream fs, int index) 
{ 
    if (fs != null) 
    { 
     BinaryFormatter binaryformatter = new BinaryFormatter(); 
     bool isFinished = false; int count = 0; 
     while (isFinished == false) 
     { 
      try 
      { 
       object objectdeserialized = binaryformatter.Deserialize(fs); 
       if (count == index) return objectdeserialized; 
       count++; 
      } 
      catch 
      { 
       isFinished = true; 
       return null; 
      } 
     } 
    } 
    return null; 
} 

эти коды будут «Еогеасп» каждый объект, который был сериализован, а затем десериализован каждый объект. Я ставлю, что мои коды не лучший способ, потому что для десериализации объекта, который содержит 100 МБ, может быть, это займет много времени, я даже не знаю, что объект, кроме индекса, который когда-либо будет десериализован, будет удален или нет? Я хочу, чтобы метод был как «Сериализационный прыжок».

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

Благодаря раньше ..

+0

Показать код, который сериализует список. –

+0

@DarinDimitrov serializing Объект списка, который я имею в виду: binaryformatter.Serialize (новый список ()); Давайте просто скажем, что в новом списке есть много элементов (), после чего я сериализую его. – Ricks

+0

Но если у вас есть много элементов в списке, как они вписываются в память? Я думал, что это была ваша проблема в первую очередь - нехватка памяти, потому что список слишком велик. –

ответ

1

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

  • префикс для каждого объекта с количеством данных, которые он принимает, путем сериализации в MemoryStream, хранение .Length (любым способом, который удобно вам, достаточно 4 байтового младшего члена), а затем скопируйте данные, которые вы написали, на MemoryStream; то вы можете перейти к n-му элементу с помощью n-times- (читать 4 байта как int, пропуская столько байтов)
  • в отдельном индексе, сохраните .Position базового потока непосредственно перед сериализацией каждого объекта; затем прочитать п-й объект, можно использовать индекс, чтобы найти место, вам нужно, и выберите там

На самом деле, вы были очень повезло здесь: BinaryFormatter на самом деле не документированы как безопасно добавить, но, как это происходит делает kinda work out ОК, вы это делаете, но это неверно для всех форматов сериализации.

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

+0

Хорошо, я понял. с вашим вторым решением, теперь проблема в том, что мы получили всю ** индекс/длину позиции ** после сериализации всего объекта, который у меня есть. Итак, как я могу поместить ** «Index/Position» ** в заголовок файла, пока мы выполнили сериализацию до 6 раз. как я могу установить положение 0 для сериализации заголовка, в то время как поток Serialization получает ошибку, потому что позиция неопрятная. – Ricks

+0

@ Rizky вы не можете магически перемещать вещи в «заголовок» файла после факта; во-первых, вам нужно переместить *** все остальные данные ***, а во-вторых: это * изменяет смещения * - хотя для этого вы, возможно, просто обманываете, смещая все по размеру заголовка. Но в этот момент вы сделали вещи принципиально неприемлемыми, поэтому почему я использовал слово «отдельный», что позволит вам продолжать использовать его так, как вы. Если вам нужен один файл, ** и ** вы хотите, чтобы он был добавочным, вам нужно было бы использовать первый подход или другой сериализатор./ –

+0

Я следил за вашими советами, это было сделано! я прочитал ваш совет, что это использует ** MemoryStream **, затем скопируйте содержимое данных и положение индекса, это тоже работает! Я очень благодарен вам, но это еще не решило мою другую проблему. теперь вернемся к моему вопросу: мне нужно сериализовать данные с объемом до 100 МБ на объект. с этим размером, даже если мне нужно сериализовать 20 объектов, мне нужно обработать все сразу в memystream, размер будет достигнут 2 ГБ в Process Memory! это вызовет ** Сбой программы **, конечно, эта проблема довольно сложная. – Ricks

Смежные вопросы