Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
.NET 4.x

Поиск и substring, как разобрать файл, сериализованный на C++

05.07.2014, 22:28. Показов 1392. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Кто-то когда-то сериализовал таблицу в файл. Делал он это на C++. Исходники утеряны, но результат сериализзации остался
Текстовый массив я из файла вроде как получил (десериализовать я просто не знаю во что, поэтому в лоб). Получилась некая каша из текстовых данных и всяких unicode символов (данные прочитались только как unicode).
Пример кусочка данных:
߿costӿ0.00׿M.oneǿ0໿Монтажǿ0௿Цехǿ0 ӿКол.ǿ1׿Кол.одинǿ0׿Материал೿NEO.00 2೿
Непечатаемые символы (в данном случае квадратики) разные, если преобразовать в char array это видно по номерам.
Результат хочу получить в виде:
Code
1
2
3
4
5
cost 0.00
M.one 0
Монтаж 0
....
Материал NEO.002
Единственное до чего пока додумался, это выцеплять текст между известными. К примеру, зная индексы cost и М.one, могу получить между ними текст. Но он будет с этими вот непечатаемыми знаками. Тоже дело решаемое, если в substring уменьшить количество текста с обеих сторон. Но есть новая напасть, какого-то текста просто может не быть, к примеру из вышепоказанной последовательности будет исключен Цех. Опять же, количество выделяемых знаков тоже может быть различно, к примеру как cost = 0.00 так и cost = 18.34444444
Нужен совет, как мне поступить?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.07.2014, 22:28
Ответы с готовыми решениями:

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

Как разобрать jar файл
как разобрать jar файл, что бы я увидел исходный код программы?

Как разобрать CSV файл?
Как известно, в CSV файле разделителями выступает знак точка с запятой. В принципе, разобрать такой файл очень легко, если только знак...

14
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
05.07.2014, 23:22
IndexOf/Split/regexp
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.07.2014, 23:26
skilllab, приложите исходный файл (или пару, если есть), возможно это бинарный формат.
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
05.07.2014, 23:33  [ТС]
Вот. Читал оттуда как массив байт. Переводил всё в
C#
1
Encoding.Unicode.GetString
Потом Regex по GUID с вычислением его индекса в строке. Дальше как описал выше, текст между двух GUID. В результате получал строку таблицы.

Дальше тёмный лес))) пока.
Вложения
Тип файла: zip Specification.zip (4.5 Кб, 3 просмотров)
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
05.07.2014, 23:46  [ТС]
Цитата Сообщение от NickoTin Посмотреть сообщение
это бинарный формат
скорее всего, ибо сохранение и чтение из этого файла связано с IStream, byte array и прочей работой в памяти. Этот файл добавляется в общий "составной документ".
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.07.2014, 23:49
skilllab, приложите еще файл, если есть, можно такого же размера и если есть меньшего (т.е. приложите 2 файла если есть)
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
05.07.2014, 23:54  [ТС]
Вот. Насчёт Specification2 не уверен что данные по формату совпадут. Я пока только самый первый приложенный файл ковырял.
Вложения
Тип файла: zip Specification1.zip (5.3 Кб, 2 просмотров)
Тип файла: zip Specification2.zip (3.5 Кб, 2 просмотров)
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.07.2014, 00:00
Сейчас еще посмотрю...

Пока такой вариант, перед каждым текстовым значением идёт последовательность вида FF FE FF XX, где XX - количество символов (не байт (!), т.е. байт будет * 2, т.к. Unicode), возможно используется тип ushort (2 байта, но первый байт устанавливается в FF, если не используется).
Т.е. можно искать последовательность FF FE FF дальше читать байт, читать строку, а вот тут я пока еще не понял, но после строк есть еще набор данных (а иногда нет), т.е. нужно снова искать последовательность FF FE FF и т.д.

Code
1
2
3
4
5
6
while (not eof)
{
     search_bytes('FF FE FF');
     length = readbyte();
     value = readstring(length * 2);
}
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
06.07.2014, 00:11  [ТС]
Точно знаю, что каждая строка в таблице содержала GUID. Для уникальности.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.07.2014, 01:15
Лучший ответ Сообщение было отмечено skilllab как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
 
namespace ConsoleApplication4
{
    class Program
    {
        class Entity
        {
            public Entity ( int offset )
            {
                Offset = offset;
            }
 
            public int Offset { get; private set; }
            public int Length { get { return 4 + Value.Length * 2; } }
            public int End { get { return Offset + Length; } }
 
            public string Value;
            public byte[] Overlay;
 
            public override string ToString ( )
            {
                return Value;
            }
        }
 
        unsafe static void Main ( string[] args )
        {
            var list = new List<Entity>();
            var buff = File.ReadAllBytes( @"X:\Specification\Specification2" );
 
            int id = 0x00FFFEFF;            // идентификатор, с которого начинается текст
            int id_bitmask = 0x00FFFFFF;    /* битовая маска, для выделения идентификатора из
                                             * 4 байтового числа. Например у нас во время чтения
                                             * есть значение 0x05FFFEFF, в нём 05 - длина строки
                                             * FFFEFF - идентификатор, наклавдывая маску 0x00FFFFFF
                                             * мы выделим идентификатор из числа и можем сравнить его
                                             * с требуемым, если же будет 0x05FFFFFF, то в результате
                                             * наложения маски получим 0x00FFFFFF, что не соответсвует
                                             * требуемому идентификатору
                                             */
            int length_bitmask = 0xFF;      // битовая маска для выделения длины из 4 байтового числа
 
            Entity entity = null;
 
            fixed ( byte* pBuff = buff )
            {
                // ptr указывает на текущее положение в потоке данных
                var ptr = pBuff;
                // окончание данных (-4 т.к. *(int*)ptr читает 4 байта)
                var end = pBuff + buff.Length - 4;
 
                while ( ptr < end )
                {
                    // если перед нами нужный идентификатор (0x00FFFEFF)
                    if ( (*(int*)ptr & id_bitmask) == id )
                    {
                        // смещение от начала данных
                        int offset = (int)(ptr - pBuff);
                        Debug.Write( offset.ToString( "D5" ) );
                        // высчитываем overlay (остаточные данные после текста, хз что)
                        if ( entity != null && entity.End != offset )
                        {
                            entity.Overlay = new byte[offset - entity.End];
                            Marshal.Copy( (IntPtr)(pBuff + entity.End), entity.Overlay, 0, entity.Overlay.Length );
                        }
                        // длина текста в символах
                        var length = (*(int*)ptr >> 24) & length_bitmask;
                        ptr += 4;
 
                        entity = new Entity( offset );
                        entity.Value = new string( (char*)ptr, 0, length );
 
                        Debug.WriteLine( "\t" + entity );
 
                        list.Add( entity );
                        ptr += length * 2;
                    }
                    else
                    {
                        ptr++;
                    }
                }
            }
 
            // в основном встречаются данные с оверлеем 4 или 6 байт, но бывают и больше
            // что там - хз... ну еще может не быть оверлея вообще
            var a = list.Where( x => x.Overlay != null && x.Overlay.Length > 6 ).ToArray();
        }
    }
}
Как это должно выглядеть в итоге знаете только Вы, поэтому составление таблицы из списка остается Вам. Все файлы прочитались без ошибок, вроде...
Использовал unsafe, т.к. так удобнее.

з.ы. Тут пропускаются первые байты до идентификатора, т.е. возможно доп. данные не после строки, а до. Тогда код будет немного другим..
2
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
16.11.2014, 01:21  [ТС]
NickoTin, доброго времени суток!
Всё работает как надо. Но, в некоторых секциях содержится текст более 550 символов. Соответственно он обрезается. Как быть, подскажите пожалуйста.

послесловие: массив с данными использую до
C#
1
 var a
, сам потом как надо выбираю.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
16.11.2014, 10:48
skilllab, приложите экземпляр файла (лучше несколько), чтобы пробовать на примере.
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
16.11.2014, 13:23  [ТС]
Вот. В файле "Specification-M 3.0 -1" есть одна секция с 729 символами (если верить Notepad++).
Узнал о количестве так:
C#
1
2
Byte[] temp = ConvertFileToByteArray("C:\\1");
var str = System.Text.Encoding.Unicode.GetString(temp);
И знал где искать и что.
Вложения
Тип файла: zip Desktop.zip (11.1 Кб, 2 просмотров)
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
16.11.2014, 15:03
После 74 строки нужно добавить этот код:
C#
75
76
77
78
79
80
                        // Если длина строки 0xFF, тогда длина находится в 2-х байтах перед текстом
                        if ( length == 0xFF )
                        {
                            length = *(ushort*)ptr;
                            ptr += 2;
                        }
Все файлы вроде нормально прочитались.
1
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,049
Записей в блоге: 1
16.11.2014, 15:34  [ТС]
NickoTin, всё супер. Спасибо огромное! Буду разбираться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.11.2014, 15:34
Помогаю со студенческими работами здесь

Как разобрать exe файл
Народ, реально ли распаковать EXE файл написанный на delphi и вычленить из него один модуль? код заведомо известный, на многих форумах...

Как разобрать и собрать jar-файл?
Итак, у меня есть .jar файл, точнее, их несколько, необходимо открыть этот .jar файл(это я могу сделать архиватором), изменить несколько...

Как передать значение в сериализованный Dictionary
В общем есть класс для сериализации (нашел в просторах инета) И есть элемент Dictionary&lt;string, List&lt;string&gt;&gt; Dic = new...

Как передать сериализованный объект по сети?
Подскажите пожалуйста. Есть Сервер (С) на с# и клиент (К) на юнити. Устанавливаем между ними сокетное подключение и пытаемся передать...

Можно ли "взломать" сериализованный файл?
Как легко это сделать ? Добавлено через 11 минут неправильно выразился : файл полученный после cериализации объектов


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита табличной части. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru