Модифицировать данные через StreamWriter или записывать в файл? - PullRequest
2 голосов
/ 30 августа 2011

Мне нужно создать двоичный файл данных. Он не может быть создан за один проход, мне нужно сериализовать некоторые данные, затем вернуться и записать смещения в заголовке. Файл будет удобно помещаться в памяти (несколько мегабайт). Могу ли я использовать BinaryWriter и вернуться к записи смещений, используя writer.Seek(x, SeekOrigin.Begin)? Или, возможно, запись в файл (а затем его изменение) имеет какие-то преимущества? Или, может быть, нет никакой разницы?

Ответы [ 2 ]

1 голос
/ 30 августа 2011

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

0 голосов
/ 30 августа 2011

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

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

Решение, которое вы спрашиваете, кажется разумным, но я верю, что BinaryWriter перезапишет, если вы попытаетесь вернуться к местоположению вашего заголовка, поэтому вам нужно будет написать блок пустых байтов, чтобы оставить себе место для написания заголовка - http://msdn.microsoft.com/en-us/library/system.io.binarywriter.seek.aspx#Y640

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

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

| --------- Chunk 1 ----------|--------- Chunk 2 -----------|
| length | name | ... | bytes | length | name | ... | bytes |

Параметр length кодирует общую длину этого чанка, затем у вас будут все свойства, которые есть у каждого чанка, а затем любые необработанные байты для сериализованного фактического объекта.

...