Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11642
Последний выпуск: 19.06.2015

C# Сериализациядесериализация классов в бинарный файл

82K
06 октября 2015 года
rom_ursus
7 / / 17.02.2015
Доброго здоровья!

Хочу сериализовать класс (содержит несколько структур). Первоначально писал в текстовый файл: 1 строка = 1 экземпляр класса. Столкнулся с проблемой - необходимо считывать последнюю строку, чтобы узнавать последний ID. Но произвольный доступ отсутствует, что вынуждает загружать весь файл. Данных предполагается много, так что этот вариант не подходит. Посему пришел к необходимости писать в бинарный файл. и вот тут подходим к самой сути вопроса:

Как правильно осуществлять хранение (запись) данных в бинарном файле?
Пока что основная идея записывать по-членно класс в файл через BinaryWriter. Читать таким же образом восстанавливая состояние экземпляра.
Код:
namespase n1
{
    struct structHealth
    {
        byte liver;
        byte eye;
        byte brain;    
    }

    struct structCloth
    {
        uint head;
        uint chest;
        uint legs;
    }

    class Human
    {
        ulong ID;
        string Name;

        structHealth Health;
        structCloth Cloth;
    }

        public Save()
        {
              using (BinaryWriter _br = new BinaryWriter(File.OpenWrite("lstHuman")))
             {
                    _br.Write(this.ID);
                    _br.Write(Health.liver);
                    //...
                    _br.Write(Cloth.Head);
                    //...
                    _br.Write(this.Name);
              }
        }

        public Load()
        {
                //аналогично только чтение.
        }
}
Если я правильно понимаю, то все экземпляры (предположим Human[100] arrHumans), т.е. их члены будут записаны в бинарный файл поочередно. Файл будет представлять собой блок данных. И только потому что в функции Load() прописано почленное чтение экземпляры будут восстановлены в исходном виде.
строковый член Name, как водится будет переменной длинны. Как в таком случае организовать произвольный доступ? Ведь блоки данных будут разной длинны.
258
08 октября 2015 года
koodeer
1.2K / / 02.05.2009
1. Предлагаю не изобретать велосипед, а использовать готовую СУБД. Например, SQLite.

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

Для удобства определяем константу с размером и создаём дополнительный метод:
Код:
const int NAME_SIZE = 20;

char[] getFixedSizeArray(string name)
{
    if (name.Length > NAME_SIZE)
        throw new ArgumentOutOfRangeException("name");

    char[] result = new char[NAME_SIZE];
    name.CopyTo(0, result, 0, name.Length);
    return result;
}
Запись и чтение производим как-то так:
Код:
using (FileStream fs = File.OpenWrite("test.bin"))
using (BinaryWriter writer = new BinaryWriter(fs))
{
    writer.Write(id);
    writer.Write(getFixedSizeArray(name));
}

using (FileStream fs = File.OpenRead("test.bin"))
using (BinaryReader reader = new BinaryReader(fs))
{
    id = reader.ReadInt32();
    name = new string(reader.ReadChars(NAME_SIZE)).TrimEnd('\0');
}
Аналогично поступаем со всеми строковыми полями/свойствами.
Таким образом, все записи будет одинаковой длины и можно перемещаться к любой по индексу и свободно её перезаписывать.

Однако, можно словить нехилые грабли, если в строках будут юникодные суррогатные пары. Какую кодировку выбрать (в Binary райтере и ридере), чтобы избежать проблем - предлагаю поломать голову самостоятельно.
82K
08 октября 2015 года
rom_ursus
7 / / 17.02.2015
Благодарю за ответ.
Каюсь, не уточнил область применения, и где вообще это всё.

В качестве хобби пишу логику игры. Предполагается значительный массив данных на каждого юнита, не говоря уже о ГГ. В серьёз подумываю о хранении сего дела в SQL базе. Единственное что не знаю как это скажется на быстродействии. Пока что все на этапе разработки и намётки. Сейчас намерен написать генератор персонажей, хотелось бы куда то сохранять, поэтому и возникли такие вопросы.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог