none
чтение файла .DAT RRS feed

  • Вопрос

  • Имеется такая структура описывает заголовок некоего .DAT файла.( 1 байт метка и 37 байт заголовок)

        public struct TitleQFile
        {
            public UInt32 metka;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
            public char[] Title;
    
        }
    
    

    считываю его вот таким кодом:

    
                FileStream fiq = new FileStream(fileq, FileMode.Open);
                TitleQFile titleq = new TitleQFile();
                var headersize = Marshal.SizeOf(titleq);
                try
                {
                    var buffer = new byte[headersize];
                    fiq.Read(buffer, 0, headersize);
                    var headerPtr = Marshal.AllocHGlobal(headersize);
                    // Копируем считанные байты из файла в выделенный блок памяти
                    Marshal.Copy(buffer, 0, headerPtr, headersize);
                    // Преобразовываем указатель на блок памяти к нашей структуре
                    titleq = (TitleQFile)Marshal.PtrToStructure(headerPtr, typeof(TitleQFile));
                }
                catch
                {
                    fiq.Close();
                    return false;
                }
    

    далее требуется прочитать около 1000 записей со след структурой: UInt32,UInt32 и так 8 раз.

    после чтения заголовка, св-во в fiq показывает что указатель указывает на 48-й байт(0-47 считаны), однако когда я читаю след.структуру, то указатель проскакивает на 3 байта вперед. и мне приходится возвращать его на 3 назд (            fiq.Seek(-3, SeekOrigin.Current);)

    дальше читается структура нормально(все 1000 записей)

    почему так происходит? и как вернопрочитать структуры (одну за другой)

    19 марта 2012 г. 18:49

Ответы

  • Размер структуры в вашем коде - 44 байта, из-за выравнивания в 4 байта по умолчанию. Вот так будет 41 байт (4+37):

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct TitleQFile
        {
            public UInt32 metka;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
            public char[] Title;
        }


    • Изменено PashaPashModerator 21 марта 2012 г. 11:46
    • Помечено в качестве ответа anknown123455 21 марта 2012 г. 14:24
    21 марта 2012 г. 11:45
    Модератор

Все ответы

  • Здравсвтуйте.

    Проверьте возвращаемое значение функцией Read, совпадает ли оно с ожидаемым значением headersize? Также метод Read больше нигде не вызывается?


    Для связи [mail]

    20 марта 2012 г. 5:01
  • Имеется такая структура описывает заголовок некоего .DAT файла.( 1 байт метка и 37 байт заголовок)

        public struct TitleQFile
        {
            public UInt32 metka;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
            public char[] Title;
    
        }
    

    Я что-то не понял.

    Вы пишите: "1 байт метка", а в коде четырёх байтовое целое UInt32 metka.

    Вы пишите: "37 байт заголовок", а в коде char[] Title - массив чаров, которые являются двухбайтовыми.

    И я не вижу причины, зачем здесь используется маршалинг. Почему бы не использовать для чтения данных BinaryReader?

    20 марта 2012 г. 13:52
  • "зачем здесь используется маршалинг. Почему бы не использовать для чтения данных BinaryReader?"

    А еще проще - создавайте и читайте текстовые файлы - просто и красиво, и просматривать легко, в том числе и в Excel-е, а значит с фильтрами, 
    с сортировками и пр. текстовыми наворотами. Скорость чтения - ~ 50 мБ/сек или ~ 1.000.000 записей по 50 байт - куда еще больше...

    20 марта 2012 г. 14:42
  • "зачем здесь используется маршалинг. Почему бы не использовать для чтения данных BinaryReader?"

    А еще проще - создавайте и читайте текстовые файлы - просто и красиво, и просматривать легко, в том числе и в Excel-е, а значит с фильтрами, 
    с сортировками и пр. текстовыми наворотами. Скорость чтения - ~ 50 мБ/сек или ~ 1.000.000 записей по 50 байт - куда еще больше...

    Эти файлы создаются сторонней программой. рад бы использовать тектсовые, да только там они двоичные..

    "Вы пишите: "1 байт метка", а в коде четырёх байтовое целое UInt32 metka."  -  опечатался.. конечно 4 байта..

    " И я не вижу причины, зачем здесь используется маршалинг. Почему бы не использовать для чтения данных BinaryReader?"

    раньше не было проблем с четением данных в структуры. поэтому использовал то что нашел.

    если приведете пример кода, буду рад.


    21 марта 2012 г. 6:48
  • Здравсвтуйте.

    Проверьте возвращаемое значение функцией Read, совпадает ли оно с ожидаемым значением headersize? Также метод Read больше нигде не вызывается?


    Для связи [mail]

    результаты при трассировке выполнения:

    int mm= fiq.Read(buffer, 0, headersize);
    hedersize = 44

    buffer - длина 44

    mm = 44


    21 марта 2012 г. 6:54
  • Вот кусок метода с момента открытия и закрытия файла:

                FileInfo fi = new FileInfo(fileq);
                if (!fi.Exists) return (false);
    
                FileStream fiq = new FileStream(fileq, FileMode.Open);
                 TitleQFile titleq = new TitleQFile();
                var headersize = Marshal.SizeOf(titleq);
                try
                {
                    var buffer = new byte[headersize];
                    int mm= fiq.Read(buffer, 0, headersize);
                    var headerPtr = Marshal.AllocHGlobal(headersize);
                    Marshal.Copy(buffer, 0, headerPtr, headersize);
                    titleq = (TitleQFile)Marshal.PtrToStructure(headerPtr, typeof(TitleQFile));
                }
                catch
                {
                    fiq.Close();
                    return false;
                }
                fiq.Seek(-3, SeekOrigin.Current);
                ElementQ eleq = new ElementQ();
                var elesize = Marshal.SizeOf(eleq);
                try
                {
                    var buffer = new byte[elesize];
    
                    while (true)
                    {
    
                        int rd = fiq.Read(buffer, 0, elesize);
                        if (rd < elesize)
                        {
                            break;
                        }
    
                        var headerPtr = Marshal.AllocHGlobal(elesize);
                        Marshal.Copy(buffer, 0, headerPtr, elesize);
                        eleq = (ElementQ)Marshal.PtrToStructure(headerPtr, typeof(ElementQ));
                        BaseC cnd = new BaseC();
                        cnd.Element = eleq;
                        this.Add(cnd);
                    }
                }
                catch
                {
                    fiq.Close();
                    return (false);
                }
                fiq.Close();
                return (true);
    

    21 марта 2012 г. 7:05
  • Размер структуры в вашем коде - 44 байта, из-за выравнивания в 4 байта по умолчанию. Вот так будет 41 байт (4+37):

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct TitleQFile
        {
            public UInt32 metka;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
            public char[] Title;
        }


    • Изменено PashaPashModerator 21 марта 2012 г. 11:46
    • Помечено в качестве ответа anknown123455 21 марта 2012 г. 14:24
    21 марта 2012 г. 11:45
    Модератор
  • Спасибо! все получилось!

    21 марта 2012 г. 14:24