Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Как записать структуру в файл не используя сериали


Автор: Igoreck 28.7.2008, 22:52
Как записать структуру в файл не используя сериализацию. Проблема в том , что при сериализации записывается много служебной информации, а у меня должна производиться запись через несколько секунд в течении долгого времени и тут размер каждой записи становится критичным. 

  
Пусть у нас есть упрощенная структура с одной переменной:

Код

public struct TEMPER 
    {
    public int tempr_air;      // температура воздуха

                 }


Я решил попробывать записать через  байтовый массив. Пришлось создать функию с использованием "небезопасного"  (unsafe)  кода - иначе не работала функция определения размера структуры : 


       
Код

 unsafe int write1()
        {
            int w;
            w = sizeof(TEMPER);
            TEMPER temp1 = new TEMPER();
            Random fixRand = new Random();
            temp1.tempr_air = (fixRand.Next()) % 11 + 391;
            Stream stream1 = new FileStream("E:\\temperature.bin", FileMode.Append, FileAccess.Write, FileShare.None);
            stream1.Write((????????, 0, w);  // вместо вопросов в качестве параметров в эту функцию надо передать массив byte[], в который надо    //преобразовать мою структуру
            stream1.Close();   
        }


можно ли преобразовать структуру в массив переменных типа byte?   Если можно - то как. Или есть какое-нибудь более красивое решение моего вопроса

Автор: Partizan 28.7.2008, 23:05
Igoreck, а вы какую сериализацию использовали?
BinaryFormatter ом не пробовали?

Автор: Igoreck 29.7.2008, 09:59
to Partizan  "BinaryFormatter ом не пробовали?"  - вот им как раз и пробывал))  - все записалось- только к 50 байтам полезной информации добавилось почти целый Кб служебной ((

Автор: Partizan 29.7.2008, 11:08
ну вообще тут могут пригодиться функции Marshal.StructureToPtr и Marshal.PtrToStruct

Автор: Igoreck 30.7.2008, 19:27
to Partizan  - большое спасибо за совет - эт то что надо)))) - вроде все получилось :

функция преобразования из файла в структуру:

 
Код

{
            TEMPER temp2 = new TEMPER();
            byte[] buf1 = new byte[Marshal.SizeOf(temp2)];
            IntPtr tp = Marshal.AllocHGlobal(Marshal.SizeOf(temp2));
            try
            {
                Stream stream1 = new FileStream("E:\\temperature.bin", FileMode.Open, FileAccess.Read, FileShare.None);
                stream1.Seek((Marshal.SizeOf(temp2))*4, SeekOrigin.Begin);
                stream1.Read(buf1, 0, buf1.Length);
                Marshal.Copy(buf1, 0, tp, buf1.Length);
                temp2 = (TEMPER)Marshal.PtrToStructure(tp, typeof(TEMPER));
                this.label1.Text = (temp2.tempr_air).ToString();  
                stream1.Close();

            }
            finally
            {
                Marshal.FreeHGlobal(tp);
            }

        }



и наоборот -  из структуры в байтовый массив и записи в файл :

Код

{
            TEMPER temp1 = new TEMPER();
            byte[] buf = new byte[Marshal.SizeOf(temp1)];
            IntPtr tp = Marshal.AllocHGlobal(Marshal.SizeOf(temp1));
            try
            {
                Random fixRand = new Random();
                temp1.tempr_air = (short)((fixRand.Next()) % 11 + 391);
                Marshal.StructureToPtr(temp1, tp, false);
                Marshal.Copy(tp, buf, 0, buf.Length);
                Stream stream1 = new FileStream("E:\\temperature.bin", FileMode.Append, FileAccess.Write, FileShare.None);
                stream1.Write(buf, 0, buf.Length);
                stream1.Close();
            }
            finally
            {
                Marshal.FreeHGlobal(tp);
            }
}



и что особо радует - удалось избежать использования unsafe кода ))

Автор: PashaPash 30.7.2008, 19:57
Igoreck, может лучше в сторону баз данных посмотри? Код будет даже меньше, чем для записи в файл. И не придется изобретать велосипед.

Автор: Igoreck 30.7.2008, 21:29
to  PashaPash - с базами данных я работал только на фоксе - давно и мало  - а с файлами   - много и на С++ . На шарпе правда еще ни с тем ни другим не работал - но решил, что с файлами мне будет проще разобраться - хотя может я еще и поменяю точку зрения в процессе работы))

Автор: Partizan 30.7.2008, 21:36
а какой смысл в базе данных, если всего-то и надо что сериализовать парочку объектов?

Автор: PashaPash 30.7.2008, 21:50
Цитата(Partizan @  30.7.2008,  21:36 Найти цитируемый пост)
а какой смысл в базе данных, если всего-то и надо что сериализовать парочку объектов? 

вообще-то задача, насколько я понял - запись показаний датчика температуры. куча одинаковых записей, по записи в пару секунд, в течении долгого времени - это совсем не "парочка объектов". Это пару десятков тысяч записей в сутки. Очень интересно будет посмотреть как по этой "парочке сериализованных объектов" будут строить статистику за месяц.
Igoreck, все зависит от объема данных и от того, как их потом собираешься использовать.

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