Низкоуровневое чтение Compound-файлов (без использования внешних компонент и утилит)

Опубликовал andrewks в раздел Программирование - Инструментарий

Низкоуровневое чтение Compound-файлов (без использования внешних компонент и утилит)

Обработка производит низкоуровневое извлечение данных из Compound-файлов (без использования внешних компонент и утилит).

Код был написан с нуля, после изучения структуры хранения данных в Compound-файле.

Использованы только штатные возможности 1С 7.7 + объект системы ADODB.Stream.

Скачать файлы

Наименование Файл Версия Размер
ЧтениеCompound.zip
.zip 7,79Kb
01.02.12
38
.zip 7,79Kb 38 Скачать

См. также

Комментарии
1. Алексей Плутенко (Noy) 1054 02.02.12 00:40 Сейчас в теме
Когда уже будем редактировать md из под предприятия???
:D
2. andrewks 1184 02.02.12 08:35 Сейчас в теме
(1) светлое будущее не за горами :)
3. Виктор Клименко (dicwork) 02.02.12 09:40 Сейчас в теме
Чтение чтением, но интерес представляла бы возможность внесения изменений без приостановки работы. А так это исследование ради спортивного интереса.
4. Ёпрст (Ёпрст) 1015 02.02.12 10:41 Сейчас в теме
че-то как-то не видно практического применения
:(

"прочитать" и блокнотом можно
5. Александр Лыткин (TrinitronOTV) 02.02.12 12:35 Сейчас в теме
(4) Ёпрст, согласен с вами, не представляю, как это можно использовать
6. andrewks 1184 02.02.12 16:22 Сейчас в теме
(4) был бы инструмент - применение найдётся. навскидку - можно заложить код проверки на "битость" мдэшника для распределённых баз, ведь на филиалах/точках, как правило, нет технических специалистов. при старте - если дата/время изменилось (накатили изменение конфы из центра), считываем структуру, при наличии ошибок бьём тревогу.
да, конечно, Compound.dll никто не отменял, но если можно обойтись штатными средствами - то почему нет?
хотя, конечно, эти штатные средства доставляют - чтение приходиться делать практически побайтно из текстового потока, т.к. 1с по-другому не умеет, и на нулях спотыкается, из-за этого и время анализа структуры приличное на больших файлах типа .md. но сам код, на мой взгляд, получился довольно стабильным, тестировал и на маленьких, и на больших файлах, и на 1с-овских, и на .doc/.xls.

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

а насчёт блокнота - много ты им начитаешь :)
7. Ёпрст (Ёпрст) 1015 02.02.12 17:45 Сейчас в теме
скажем так, блокнотом с поддержкой hex редактора - всё что нужно
8. andrewks 1184 02.02.12 18:38 Сейчас в теме
(7) и по какому алгоритму ты ищешь нужный поток в hex-редакторе?
9. Ёпрст (Ёпрст) 1015 06.02.12 11:19 Сейчас в теме
мот тебе описалово компаунд файла скинуть ?
:)
там всё есть.. и про заголовки и про смещения.
10. andrewks 1184 06.02.12 11:24 Сейчас в теме
(9) у меня и у самого есть описание. просто это жутко неудобно - в хекс-редакторе нужный поток искать "по правильному". ну, а если ищешь по начальным символам потока (ну там, моксель, диалог, и т.п.) - это другое дело.
однако тут есть нюанс - по структуре компаунда, поток далеко не обязательно идёт неразрывно от начала до конца. но, с другой стороны, как я понял, 1с старается впихивать неразрывно. соблюдается ли это в 100% случаях для компаундов, записанных 1с, или нет - не проверял
11. Василий Казьмин (awk) 668 06.02.12 12:22 Сейчас в теме
(0)
Обработка производит низкоуровневое извлечение данных из Compound-файлов (без использования внешних компонент и утилит).

И тут же:
+ объект системы ADODB.Stream.


Класс. А вообще есть такая ole32.dll. Там все методы для работами с такими файлами есть...

[DllImport("ole32.dll", CharSet = CharSet.Unicode)]
public static extern int StgIsStorageFile(string fileName);
[DllImport("ole32.dll")]
public static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)]string pwcsName, IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstgOpen);
...Показать Скрыть

и т.д.
12. andrewks 1184 06.02.12 13:20 Сейчас в теме
(11) с чем вы не согласны? с тем, что СоздатьОбъект() - штатный функционал 1с? никаких обёрток, скриптов, специальных внешних длл нет.
"А вообще есть такая ole32.dll." естественно, я в курсе, а теперь покажите мне пример работы с этими методами, используя _только_ штатные средства 1С? и, во-вторых, код их закрыт, поэтому не получится управлять поведением алгоритма при возникновении ошибок разного характера
13. Василий Казьмин (awk) 668 06.02.12 13:50 Сейчас в теме
(12)
1. Тогда по твоей логике:
AMD=СоздатьОбъект("ActiveMD.MDFile");

то же штатно?

2. Тебе показать обертку на С#, что бы так же "штатно" как в твоем примере заработало?

3. Код конечно у ole32.dll закрыт, но вот функции имеют вполне нормальное описание на MSDN.

А теперь немного для твоего просветления. Функция "СоздатьОбъект" создает не только объекты 1С, но и другие, к 1С никакого отношения не имеющие. А объекты которых в 1С нет - называются внешними. ADODB.Stream - это типичный, внешний, COM объект.
14. Ёпрст (Ёпрст) 1015 06.02.12 13:58 Сейчас в теме
(13) тут просто лукавство - раз в коде не пишем Загрузитьвнешнююкомпоненту, то вроде как их и не "используем"
:)

хотя да, методы адо как и есть внешние компоненты..
15. andrewks 1184 06.02.12 14:11 Сейчас в теме
(13)
вы, конечно, лихо жонглируете, но я тоже не пальцем деланный.
"AMD=СоздатьОбъект("ActiveMD.MDFile");" требует наличия вполне определённого com-сервера из ActiveMD.dll, и никоим образом не относится ни к штатному функционалу 1С, ни к штатному функционалу системы.
про "аргумент" с С# я вообще молчу.

ADODB.Stream заведомо есть (с вероятностью, стремящейся к 1) в любой win-системе. более того, этот объект используется исключительно из-за необходимости обойти всем известные ограничения встроенного объекта Текст.
так что непонятна суть ваших придирок. если хотите, можете специально для себя сделать на основе этого исходного кода "cut-edition", заменив ADODB.Stream на Текст (с соответствующими ограничениями). суть работу алгоритма от этого не изменится

"Код конечно у ole32.dll закрыт, но вот функции имеют вполне нормальное описание на MSDN. " а я что, где-то утверждал обратное?
16. Василий Казьмин (awk) 668 06.02.12 14:51 Сейчас в теме
(15)
1. Я не жонглирую.
2. Естественно
ActiveMD.dll, и никоим образом не относится ни к штатному функционалу 1С, ни к штатному функционалу системы.
для этого я его и привел.
3. Не нравится С# возьми С++ http://infostart.ru/public/115486/. Сути не поменяет. ADODB.Stream - внешний объект.
4.
"ADODB.Stream" заведомо есть.
Не во всех версиях есть.
5. И какие же ограничения у встроенного объекта "Текст"? Наверно, разработчики не предусмотрели делая объект для чтения текста, что им бинарники читать начнут?
6.
"А вообще есть такая ole32.dll." естественно, я в курсе, а теперь покажите мне пример работы с этими методами, используя _только_ штатные средства 1С? и, во-вторых, код их закрыт, поэтому не получится управлять поведением алгоритма при возникновении ошибок разного характера
Я наверно не понял какие ошибки вы ввиду имеете. Те ошибки, которые возникали у меня, вполне себе обрабатывались и алгоритм вполне себе управляемый был. Кстати, ADODB.Stream то же не OpenSource.
17. andrewks 1184 06.02.12 15:18 Сейчас в теме
(16) не совсем понятны ваши намёки на C# и С++. предлагаете взять, и написать сто пятидесятый ридер compound, в добавок к уже имеющимся Compound.dll, ActiveMD.dll, gcomp, и прочим? это неинтересно, и это, на мой взгляд, лишено смысла. идея состояла именно на полноценной реализации алгоритма исключительно в рамках встроенного языка 1С.
Мой алгоритм чтения Compound целиком и полностью уложен в стандартный синтаксис встроенного языка 1С, я это хотел подчеркнуть, что внутри - не вызов нарытого в инете vbs-скрипта, и не вызов методов Compound.dll или ole32, завёрнутый в скрипт.

"Я наверно не понял какие ошибки вы ввиду имеете. Те ошибки, которые возникали у меня, вполне себе обрабатывались и алгоритм вполне себе управляемый был. Кстати, ADODB.Stream то же не OpenSource. "
ну вот, а говорите, что не жонглируете. с исходного кода алгоритма чтения Compound перескочили на исходный код алгоритма чтения текста из потока. т.е., на ваш взгляд, это одно и то же?
а ошибки я имел в виду в структуре Compound (ошибки в FAT, MimiFAT, Directory, некорректные цепочки, и т.п.)
18. andrewks 1184 06.02.12 15:20 Сейчас в теме
(16) "И какие же ограничения у встроенного объекта "Текст"? " ну, начнём с самого главного - это ограничение на объём данных. в принципе, на этом можно и закончить, т.к. одного этого пункта уже достаточно
19. Василий Казьмин (awk) 668 06.02.12 15:46 Сейчас в теме
(17),(18)
не совсем понятны ваши намёки на C# и С++. предлагаете взять, и написать сто пятидесятый ридер compound, в добавок к уже имеющимся Compound.dll, ActiveMD.dll, gcomp, и прочим? это неинтересно, и это, на мой взгляд, лишено смысла. идея состояла именно на полноценной реализации алгоритма исключительно в рамках встроенного языка 1С. Мой алгоритм чтения Compound целиком и полностью уложен в стандартный синтаксис встроенного языка 1С, я это хотел подчеркнуть, что внутри - не вызов нарытого в инете vbs-скрипта, и не вызов методов Compound.dll или ole32, завёрнутый в скрипт.
Здорово, молодец. За идею и саморазвитие пять...

ну вот, а говорите, что не жонглируете. с исходного кода алгоритма чтения Compound перескочили на исходный код алгоритма чтения текста из потока. т.е., на ваш взгляд, это одно и то же?

Не, не жонглирую. На уровне 1С это одно и то же. Это вызов метода внешней компоненты..

а ошибки я имел в виду в структуре Compound (ошибки в FAT, MimiFAT, Directory, некорректные цепочки, и т.п.)
Ну эти вполне обрабатываемые. От закрытости/открытости кода не зависит.

это ограничение на объём данных
И сколько max memory size?


P.S. Я это к чему? Я к тому что в описании ошибка про неиспользование внешних компонент. А про ole32.dll я вспомнил т.к. думал, что разработка для дела нужна, а не для спортивного интереса (на подобии "Как палочками суп есть").
20. andrewks 1184 06.02.12 23:00 Сейчас в теме
(4) как и обещал, придумал применение.
http://infostart.ru/public/115930/
(на данный момент публикация отправлена на модерацию)
да это жуткий изврат, но зато красиво!
21. andrewks 1184 06.02.12 23:01 Сейчас в теме
22. Ильдар Гайсин (gia2011) 08.02.12 09:00 Сейчас в теме
Для изменения компаундных файлов необходимо иметь программу для просмотра и редактирования составных файлов. В этом качестве я использую плагин DocFile Browser для файлового менеджера FAR Евгения Рошаля (официальный сайт этого файлового менеджера — http://www.farmanager.com/ ). Упомянутый плагин можно найти на сайте http://www.7-zip.org/ его автора — Игоря Павлова, в разделе Утилиты.
23. andrewks 1184 08.02.12 10:46 Сейчас в теме
(22) само по себе чтение и/или изменение составных файлов давно перестало быть проблемой, есть куча разных инструментов (gcomp, activemd.dll, compound.dll, vbs-скрипты по чтению и извлечению данных, вышеупомянутый плагин, и ещё много чего), и в последнее время даже архиваторы (причём даже под линукс) научились извлекать файлы из таких "архивов", например, в последних версиях 7-zip это реализовано.
моя разработка - это просто пример реализации во-первых, на языке 1С, во-вторых, низкоуровневого доступа, без привлечения WinAPI
24. nelse (nelse) 08.02.12 18:43 Сейчас в теме
(6) andrewks,
зачем блокнотом? есть нормальные расширения к TotalCommander.
А вот вопрос практического применения остается.
25. Ловыгин Антон (wunderland) 191 10.02.12 12:46 Сейчас в теме
За проделанную работу однозначно "+".
Сам когда-то возился с разными спец. файлами с описанием формата на 200-300 стр. на аглицком...
26. Саня Пупкин (pupkinSana) 20 15.02.12 07:57 Сейчас в теме
(1) Редактировать МД можно на лету давно. Достаточно оборвать связи ссылок на МД-файл - можно анлокером, (я себе писал ертешку прямо из 1С редактировать свой же МД) и уже редактировать любым мд-редактором. Даже стандартным конфигуратором открывать свободный МД. Единственное, можно редактировать без изменений метаданных - только поправить модули. Потом кому нужно - пусть перезапускают у себя 1С.

Вопрос автору: а назад можно ли придумать компилировать Compound-файл?
27. andrewks 1184 15.02.12 14:33 Сейчас в теме
(26) что имеется в виду под "компилировать"? если запись и/или изменение потоков в Compound - то да, конечно, технически это реализуемо в рамках тех же средств, что и в представленной обработке по чтению (т.е. "голый" язык 1С + объект системы Adodb.Stream)

мысль по реализации этих возможностей у меня была, и даже пока ещё есть. только немного смущают замечания по поводу бесперспективности в практическом применении и + сейчас немного не до этого, не хватает времени.
но, вполне возможно, в не столь отдалённом будущем у меня дойдут-таки руки до этого, тогда непременно выложу апдейт сюда.

дополнительно удручает тормознутость схемы посимвольного чтения из текстового потока (это необходимо из-за невозможности работы 1С с очень длинными строками, и + невозможность работы со строками, содержащими нули), поэтому, конечно, реализация через внешнюю компоненту работает гораздо быстрее