![]() |
![]() |
![]() |
|
Как хотя бы грубо определить размер будущего файла из ЗаписьXML? | ☑ | ||
---|---|---|---|---|
0
TormozIT
гуру
01.10.09
✎
12:48
|
сабж
|
|||
1
H A D G E H O G s
01.10.09
✎
12:54
|
Ощутите прелесть XML-я.
|
|||
2
asady
01.10.09
✎
12:55
|
(0) посчитать количество символов и умножить на 4
|
|||
3
H A D G E H O G s
01.10.09
✎
12:56
|
(2) На 2
|
|||
4
luns
01.10.09
✎
12:57
|
если пишутся однотипные данные (например справочник), то можно наверное сначала записать кусок и по его размеру попытаться определить...
|
|||
5
asady
01.10.09
✎
13:04
|
(3) в юникоде?
|
|||
6
H A D G E H O G s
01.10.09
✎
13:07
|
(5) Аникод аникоду рознь.
Есть 1, 2 , 4 байт/символ уникод. Но обычно - 2 байта. |
|||
7
TormozIT
гуру
01.10.09
✎
13:08
|
(2) Как посчитать количество символов, не закрывая поток (без ощутимых потерть производительности)?
|
|||
8
Живой Ископаемый
01.10.09
✎
13:08
|
2(6) Да, но обычно пишутся не толко данные но и метададнные. в смысле тег открывается и закрывается имененм реквизита/объекта.. Так что на 4. :)
|
|||
9
asady
01.10.09
✎
13:10
|
(7) как вариант: писать в поток кусками по 512 байт например и считать куски.
|
|||
10
asady
01.10.09
✎
13:12
|
ты поток сишный юзаешь?
там все функции вывода возвращают количество выведенных объектов |
|||
11
H A D G E H O G s
01.10.09
✎
13:12
|
Счаст опять заумных вещей понапишу и вспугну вас...
|
|||
12
H A D G E H O G s
01.10.09
✎
13:13
|
(10) Я как бы думаю, что тема как бы подразумевает 1С v8...
|
|||
13
TormozIT
гуру
01.10.09
✎
13:14
|
ЗаписьXML (XMLWriter)
ЗаписьXML (XMLWriter) Свойства: КонтекстПространствИмен (NamespaceContext) Отступ (Indent) Параметры (Settings) Методы: Закрыть (Close) ЗаписатьАтрибут (WriteAttribute) ЗаписатьБезОбработки (WriteRaw) ЗаписатьИнструкциюОбработки (WriteProcessingInstruction) ЗаписатьКомментарий (WriteComment) ЗаписатьКонецАтрибута (WriteEndAttribute) ЗаписатьКонецЭлемента (WriteEndElement) ЗаписатьНачалоАтрибута (WriteStartAttribute) ЗаписатьНачалоЭлемента (WriteStartElement) ЗаписатьОбъявлениеXML (WriteXMLDeclaration) ЗаписатьСекциюCDATA (WriteCDATASection) ЗаписатьСоответствиеПространстваИмен (WriteNamespaceMapping) ЗаписатьСсылкуНаСущность (WriteEntityReference) ЗаписатьТекст (WriteText) ЗаписатьТекущий (WriteCurrent) ЗаписатьТипДокумента (WriteDocumentType) НайтиПрефикс (LookupPrefix) ОткрытьФайл (OpenFile) УстановитьСтроку (SetString) |
|||
14
H A D G E H O G s
01.10.09
✎
13:15
|
(13) Имя файла известно, так?
|
|||
15
Jolly Roger
01.10.09
✎
13:17
|
(0) зависит от данных, которые ты в этот райтер выводишь...
|
|||
16
Aprobator
01.10.09
✎
13:27
|
(0) зачем, если не секрет?
|
|||
17
GenV
01.10.09
✎
13:38
|
(0) А может параллельно частями записывать в объекто-копию ЗаписьXML и определять длину получившейся строки?
|
|||
18
TormozIT
гуру
01.10.09
✎
14:34
|
(0) + Хочется ограничить размер XML файла обмена, чтобы он не превысил заданный порог.
|
|||
19
Aprobator
01.10.09
✎
14:35
|
(18) а что мешает посмотреть размер готового, а не заниматься предсказаниями?
|
|||
20
Rebelx
01.10.09
✎
14:42
|
(0) - элементарно - выгружаешь объект - смотришь размер что получилось. умножаешь на количество. с докуентами чуть сложнее - надо количество строк учитывать.
|
|||
21
Живой Ископаемый
01.10.09
✎
14:43
|
2(19)Например - Время, затраченное на его переформирование...
|
|||
22
Найлло
01.10.09
✎
14:51
|
(18) А что ты потом будешь делать с незаписанными данными? Получается придется для них вручную регистрацию отменять, а для остальных чтоб осталось (для выгрузки во втором файле). Плюс твой алгоритм (если придумается) накроется если будут передаваться изменения конфигурации. Как итог- не парить мозг и заносить файл в архивы определенной длины. Вроде такое даже в 1С можно реализовать, чтобы архивировался с определенным размером.
|
|||
23
TormozIT
гуру
01.10.09
✎
15:03
|
Если использовать метод ВыбратьИзменения(), то
ПланыОбменаМенеджер (ExchangePlansManager) ВыбратьИзменения (SelectChanges) ... Описание: При этом в процессе выборки изменений в записи регистрации изменений проставляется номер сообщения обмена данными, в котором должны передаваться изменения. Пока я не уверен, в какой момент проставляется номер. Если в момент вызова Получить(), то можно его использовать. Если в момент непосредственно выполнения ВыбратьИзменения(), то придется сначала получать все изменения, а потом их по одному выбирать по одному через параметр <Фильтр выборки> (необязательный) Тип: Неопределено, Объект метаданных, СсылкаНаОбъект, НаборЗаписей, Массив. Неопределено - фильтр пуст, выбираются все изменения по узлу; Объект метаданных - выбираются изменения в основной таблице, связанной с данным объектом метаданных; СсылкаНаОбъект - фактически, может быть выбрана только одна запись об изменении данного объекта, либо ни одной, если объект не менялся; НаборЗаписей - набор записей регистра, может быть не выбран, для фильтрации изменений используется лишь отбор набора записей; Массив - все элементы массива имеют один из перечисленных выше типов, кроме Неопределено. Условия фильтрации соединяются по ИЛИ. Значение по умолчанию: Неопределено |
|||
24
TormozIT
гуру
01.10.09
✎
15:05
|
Если файл XML получается размером в 20 гигов, то при его распаковке из арихива в приемнике может не хватить места.
|
|||
25
TormozIT
гуру
01.10.09
✎
15:05
|
(24) Ну и в источнике конечно тоже))
|
|||
26
TormozIT
гуру
01.10.09
✎
15:06
|
(20) У меня наборы записей регистра бухгалтерии. Один может быть пустой и занимать 500 байт, в другой может быть из 100000 проводок и занимать 100 мегабайт
|
|||
27
Живой Ископаемый
01.10.09
✎
15:20
|
2(26) Посмотреть сколько занимает одна проводка по максимуму. считать проводки. Метод Количество() для набора записей работает.
|
|||
28
mrWatson
01.10.09
✎
15:22
|
размер будущего файла не больше чем размер свободного места на диске
|
|||
29
TormozIT
гуру
01.10.09
✎
15:23
|
(27) Дисперсия очень большая. Твой способ выдает размер в 100 раз больше, чем реальный
|
|||
30
TormozIT
гуру
01.10.09
✎
15:24
|
(28) Для 19-го века это может быть и полезное умозаключение, но мы живем уже в 21-м...
|
|||
31
TormozIT
гуру
01.10.09
✎
15:26
|
(27) Реквизит неограниченной длины убивает твой способ на повал.
|
|||
32
Живой Ископаемый
01.10.09
✎
15:27
|
2(29) Ну, в общем я взял твой вопрос на заметку, интересно... Попробую в течении недели что-нибудь придумать
|
|||
33
acsent
01.10.09
✎
15:27
|
(31) А если попробовать использовать DOM модель?
|
|||
34
Живой Ископаемый
01.10.09
✎
15:27
|
2(31) На всякий случай - речь идет о типовой?
|
|||
35
Живой Ископаемый
01.10.09
✎
15:28
|
(31) Страшно подумать что со способом в (27) сможет сделать реквизит типа хранилище значений :)
|
|||
36
mrWatson
01.10.09
✎
15:34
|
скажи зачем тебе это?
|
|||
37
mrWatson
01.10.09
✎
15:35
|
а всё увидел в (18)
|
|||
38
TormozIT
гуру
01.10.09
✎
15:58
|
(34) Речь идет не и типовой. Да и какая разница то?)
|
|||
39
Живой Ископаемый
01.10.09
✎
16:02
|
2(38) Ну... и тем не менее... РБ похож на РБ Хозрасчетный из Типовой? Реквизит типа строка неопределнной длины - один или несколько? В типовой просто Содержание - 50 символов
|
|||
40
TormozIT
гуру
01.10.09
✎
16:06
|
Друзья, ну что вы зациклились на РБ. Там огромный спектр объектов метаданных участвует разных цветов и мастей )
|
|||
41
Serg_1960
01.10.09
✎
16:22
|
Друзья, ну что Вы зациклились на размере XML. Предложите автору чаще делать обмен данными :)
|
|||
42
TormozIT
гуру
01.10.09
✎
16:28
|
(41) Это не защита от разовых перезаписей большого объема данных, дружище.
|
|||
43
Serg_1960
01.10.09
✎
16:32
|
Размер - как часто (и почему) для автора это актуально? Нет места? И нельзя его увеличить?
|
|||
44
Serg_1960
01.10.09
✎
16:37
|
(размышляю) Предположим, что перед формирование файла обмена, автор будет знать размер файла. Он больше, чем допустимо по каким-то там критериям. Что дальше?
|
|||
45
Serg_1960
01.10.09
✎
16:39
|
Ответ: Вместо одного большого сообщения надо передать кучу маленьких сообщений :) Видите как всё просто? Осталось найти решение :))
|
|||
46
TormozIT
гуру
01.10.09
✎
16:45
|
(45) Надо же! Ты додумался до того же, до чего и автор темы (я). Жаль только что это ему не помогло.
|
|||
47
Живой Ископаемый
01.10.09
✎
16:48
|
2(46) На самом деле можно сообщение разбивать не по размеру а по количеству объектов.. Например в одном сообщении - 1000. Разве это не способ?
Но просто нужно продумать на счет нумерации и последующего прихода квитанции... |
|||
48
Serg_1960
01.10.09
✎
16:48
|
Почему? Разве это сложно?
|
|||
49
YauheniL
01.10.09
✎
16:51
|
А разве файл XML в 8-ке нельзя формировать через строковую переменную, а потом узнать количество символов этой переменной. А потом отдать именно эту строку на растерзание XML-парсеру?
|
|||
50
Serg_1960
01.10.09
✎
16:55
|
(47) Для каждого "маленького" сообщения тупо увеличиваем номер и потом его меняем в базе. Всё это делаем на источнике. Узел последовательно принимает нашу пачку сообщений и в очередной выгрузке возвращает нужный нам номер...
|
|||
51
TormozIT
гуру
01.10.09
✎
16:59
|
(47) У меня есть в базе объекты размером по 10 мегов в сериализованном виде. Если я ставлю по 1000 объектов в сообщении, то получу одно сообщение в 10 гиг. Это неприемлемо.
|
|||
52
TormozIT
гуру
01.10.09
✎
17:00
|
(49) Как узнать размер строки XML, не затрачивая ресурсов на ее закрытие и последующее восстановление?
|
|||
53
TormozIT
гуру
01.10.09
✎
17:01
|
(52) + закрытие и восстановление объекта ЗаписьXML
|
|||
54
Serg_1960
01.10.09
✎
17:03
|
Формально, через размер файла мы узнаем на сколько частей дробить сообщение. Согласен? Но дробить сообщение будем уже по объектам. Поэтому нужно заранеее знать количество объектов или сразу подсчитывать размер при формировании "маленького" сообщения. Как дощли (плюс/минус) - начинаем следующие сообщение. Согласен, что главная засада в том, что "размеры" у разных объектов весьмя сильно отличаться могут. Но всё-таки, пусть и приближенно. Это вариант...
|
|||
55
Живой Ископаемый
01.10.09
✎
17:06
|
2(50) "Узел последовательно принимает нашу пачку сообщени" как оптимистично - а если он обламывается посредине?
|
|||
56
GenV
01.10.09
✎
17:06
|
54+ а если дробить уже готовый файл XML на куски, увеличивая номер сообщения (может быть сторонним парсером, а не 1С-ким)?
|
|||
57
Serg_1960
01.10.09
✎
17:11
|
(55) А если ток выключат, а если сервер взорвут арабы, а если... А что происходит когда "обламывается" обычное сообщение обмена?
(56) А чего там сложно? Мы же не будем парсить сами объекты. Простое последовательно чтение (по объектам) XML файла - 10 строк кода. |
|||
58
Rebelx
01.10.09
✎
17:13
|
(29) какая дисперсия для проводок??? или у тебя содержание в мегабайтах меряется?
|
|||
59
Serg_1960
01.10.09
✎
17:15
|
(52) Хм... А разве нельзя узнать размер файла, не закрывая его?
|
|||
60
TormozIT
гуру
01.10.09
✎
17:17
|
(59) Хм, а если ты знаешь способ, то что же молчишь?)))
|
|||
61
GenV
01.10.09
✎
17:19
|
(57) Тогда размер опять будет приближенным, с учетом возможных больших размеров каждого объекта. А стандартным парсером размер не узнаешь.
|
|||
62
Serg_1960
01.10.09
✎
17:19
|
(60) Хочешь предложить строем ходить? :)
|
|||
63
Serg_1960
01.10.09
✎
17:20
|
(62) + "Если вы такие умные - что-же вы строем не ходите"(с)
|
|||
64
TormozIT
гуру
01.10.09
✎
17:21
|
(63) Типа того)
|
|||
65
Serg_1960
01.10.09
✎
17:22
|
(61) А зачем мне точно "в размер" писать? Плюс, минус один объект - роли не играет :)
|
|||
66
asady
01.10.09
✎
17:24
|
(0) у объекта ЗаписьXML есть метод УстановитьСтроку()
|
|||
67
asady
01.10.09
✎
17:25
|
(66)+ почему бы не писать в эту строку как в некий промежуточный буфер
|
|||
68
YauheniL
01.10.09
✎
17:26
|
(52) А ты весь файл сам формируешь?
|
|||
69
GenV
01.10.09
✎
17:27
|
(65) Ну, так плюс, минус один объект нужно как раз и определить. Судя по (51) промахнуться с количеством объектов можно не хило. А стандартным способом только получая строку можно размер получить.
|
|||
70
Serg_1960
01.10.09
✎
17:32
|
(69) А как Вам если так: читаем объект из XML - перед записью, загоняем его в строку - получаем размер и решаем: продолжать писать или пора остановиться?
|
|||
71
TormozIT
гуру
01.10.09
✎
17:34
|
(52) Да.
|
|||
72
TormozIT
гуру
01.10.09
✎
17:36
|
(70) Драгоценный товарищ, давно бы уже пример кода запостил. Что ты все ходишь вокруг да около. Может пора уже набраться духу и написать пару строк кода, хотя бы даже без проверки.
|
|||
73
YauheniL
01.10.09
✎
17:37
|
(71) Тогда можно использовать метод "ЗаписатьБезОбработки (WriteRaw)" объекта "Запись XML" в качестве параметра туда передается сам XML-текст. Размер итогового XML-файла будет вычислен как:
ДлинаСтр(ТекстXML) * 2 * ФакторUnicod + ПоправкаНаРазмерКластера ФакторUnicod -- число, определяющее насколько больше занимает места 1 символ Unicode по сравнению с 2 |
|||
74
TormozIT
гуру
01.10.09
✎
17:38
|
(73) Спасибо. Видимо это оно.
|
|||
75
Serg_1960
01.10.09
✎
17:38
|
(72) Убил :( Я как раз слинять хотел, а то за базар отвечать придется :)
|
|||
76
TormozIT
гуру
01.10.09
✎
17:52
|
(73) Попытался применить, но понял, что не оно.
ЗаписьXML (XMLWriter) ЗаписатьБезОбработки (WriteRaw) Параметры: <Текст> (обязательный) Тип: Строка. Текст, ПОМЕЩАЕМЫЙ без обработки в формируемый документ или фрагмент XML. Что предлагается передавать туда в качестве параметра, неясно. |
|||
77
asady
01.10.09
✎
18:09
|
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку(); // Запись документа XML ... СтрXML = ЗаписьXML.Закрыть(); //тут можно узнать размер данных ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл("c:\docs\data.xml", "UTF-8"); ЗаписьXML.ЗаписатьБезОбработки(СтрXML); |
|||
78
acsent
01.10.09
✎
18:18
|
А разве записьхмл не сразу в файл пишет?
|
|||
79
asady
01.10.09
✎
18:20
|
(78) нет. может и в буфер писать
|
|||
80
acsent
01.10.09
✎
18:22
|
(78) Да, в эксклюзивном режиме пишет. Файл размером 0
|
|||
81
Serg_1960
01.10.09
✎
18:23
|
А можно проверить конструкцию? Вставить в цикл после записи объекта:
ПолныйПуть = "C:\config.sys"; // полный путь к файлу. Заполнил для примера примера :) FSO = Новый COMОбъект("Scripting.FileSystemObject"); Сообщить(FSO.GetFile(ПолныйПуть).Size); |
|||
82
acsent
01.10.09
✎
18:23
|
(77) Жестко тормозить будет на ьольших файлах
|
|||
83
YauheniL
01.10.09
✎
18:24
|
(76) Полностью файл XML (если в тотале без плагинов по Ф3 открыть, то примерно таким вот должен быть параметр
|
|||
84
asady
01.10.09
✎
18:25
|
(82) поэтому и хочет тормозИТ проверять размер.
|
|||
85
acsent
01.10.09
✎
18:26
|
ты в строку передаешь например мегабайт 100, а 1С не очень хорошо работает со строками
|
|||
86
acsent
01.10.09
✎
18:27
|
(84) Именно такая проверка будет тормозить
|
|||
87
asady
01.10.09
✎
18:28
|
(85) ТормозуИТ торомза не страшны :) он боится получить слишком большой файл обмена.
|
|||
88
TormozIT
гуру
01.10.09
✎
18:48
|
Проблема еще в том, что даже забив на тормоза после ЗаписьXML.закрыть()
сложно возвращаться на прежнее место в записи XML. Вот код, который выдает ошибку. ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); Порог = 20000; ПериодПроверкиРазмераФайла = 20; Для Счетчик = 1 По 1000 Цикл ЗаписатьXML(ЗаписьXML, Константы.ПрефиксВесовогоТовара.СоздатьМенеджерЗначения()); Если Счетчик % ПериодПроверкиРазмераФайла = 0 Тогда Строка = ЗаписьXML.Закрыть(); ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьБезОбработки(Строка); Если СтрДлина(Строка) > Порог Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; ЗаписьXML.ЗаписатьКонецЭлемента("АА"); Сообщить(ЗаписьXML.Закрыть()); |
|||
89
TormozIT
гуру
01.10.09
✎
18:51
|
(88) +
Ошибка при вызове метода контекста (ЗаписатьXML): Ошибочный порядок записи XML |
|||
90
asady
01.10.09
✎
19:58
|
(89) а зачем так?
проверил, потом пиши в другую строку и строки склеивай перед записью |
|||
91
TormozIT
гуру
01.10.09
✎
20:03
|
(90) А зачем такая сложность? Можешь объяснить почему не работает (88)?
|
|||
92
asady
01.10.09
✎
20:07
|
скорее всего при
ЗаписьXML.Закрыть(); пишется какой-то конечный тег а вот твой конечный тег ЗаписьXML.ЗаписатьКонецЭлемента("АА"); не пишется |
|||
93
TormozIT
гуру
01.10.09
✎
20:12
|
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку(); ПорогРазмераФайла = 20000; ПериодПроверкиРазмераФайла = 20; Для Счетчик = 1 По 1000 Цикл ЗаписьXML.ЗаписатьНачалоЭлемента("ББ"); ЗаписьXML.ЗаписатьКонецЭлемента(); Если Счетчик % ПериодПроверкиРазмераФайла = 0 Тогда Строка = ЗаписьXML.Закрыть(); ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьБезОбработки(Строка); Если СтрДлина(Строка) > ПорогРазмераФайла Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Сообщить(ЗаписьXML.Закрыть()); Та же ошибка. |
|||
94
TormozIT
гуру
01.10.09
✎
22:43
|
Друзья, помогите же мне.
|
|||
95
Wehrmacht
01.10.09
✎
23:34
|
(0) Аще бред. Как быть по крайней мере с такой ситуацией: а) зарегистрировалось n-ное кол-во изменений, начинаем выгружать, на трети изменений пришли к выводу, что для начала достаточно, остальное оставили на потом. В том что выгружается -- 1000 проводок, в том, что оставили на потом -- элементы справочника на которые ссылаются эти проводки. результат - битые ссылки. до след. сеанса обмена накопилось еще k-тое кол-во изменений, выгружаем... кто гарантирует, что оставшаяся часть данных из первой пачки выгрузится в этот раз (и вообще когда-либо)? б) на удаленной стороне срочно понадобился некий документ базы-источника -- сколько надо будет играть в эту русскую рулетку, чтобы гарантированно доставить объект?
|
|||
96
TormozIT
гуру
02.10.09
✎
02:53
|
(95) Мда дядя, похоже ты никогда гигабайты не прокачивал. Посмотрю я на тебя, когда тебе в базу поставят задачу залить 20 гигов XML. Будешь его в транзакции загружать? Ну-ну)
|
|||
97
asady
02.10.09
✎
10:09
|
Процедура КнопкаВыполнитьНажатие(Кнопка)
ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьОбъявлениеXML(); ПорогРазмераФайла = 500; ПериодПроверкиРазмераФайла = 5; МассивСтрок=Новый Массив; ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); Для Счетчик = 1 По 12 Цикл ЗаписьXML.ЗаписатьНачалоЭлемента("ББ"); ЗаписьXML.ЗаписатьКонецЭлемента(); Если Счетчик % ПериодПроверкиРазмераФайла = 0 Тогда ЗаписьXML.ЗаписатьКонецЭлемента(); тСтрока = ЗаписьXML.Закрыть(); МассивСтрок.Добавить(тСтрока); ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); Если СтрДлина(тСтрока) > ПорогРазмераФайла Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; ЗаписьXML.ЗаписатьКонецЭлемента(); МассивСтрок.Добавить(ЗаписьXML.Закрыть()); ВГр = МассивСтрок.ВГраница(); Сообщить("Всего кусков " + (ВГр+1)); Строка=""; Для сч =0 по ВГр Цикл Строка=Строка+МассивСтрок[сч]; КонецЦикла; ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьБезОбработки(Строка); Сообщить(ЗаписьXML.Закрыть()); КонецПроцедуры вот так работает Всего кусков 3 <?xml version="1.0"?> <АА> <ББ/> <ББ/> <ББ/> <ББ/> <ББ/> </АА><АА> <ББ/> <ББ/> <ББ/> <ББ/> <ББ/> </АА><АА> <ББ/> <ББ/> </АА> |
|||
98
Wehrmacht
02.10.09
✎
11:41
|
(96) А транзакциями по несколько сотен объектов не судьба? Вообще не вижу проблем как бы
|
|||
99
TormozIT
гуру
02.10.09
✎
12:34
|
(98) Раз не видишь, а другие видят, то значит смотришь под другим углом.
|
|||
100
TormozIT
гуру
02.10.09
✎
14:03
|
(97) Т.е. красиво решить задачу даже с тормозами не получается =(
|
|||
101
Живой Ископаемый
02.10.09
✎
14:09
|
2(100) В общем смотри, у меня была идея вывести эмперически закономерность между размером того что получается при СохранитьЗначениеВФайл() для объекта и того, сколько он занимает в ХМЛ... Но нет времени даже накидать какой-то черновик.. Так что прими идею пока на уровне бреда... Вдруг он мспособна вызреть во что-то?
|
|||
102
Serg_1960
02.10.09
✎
14:15
|
Дабы вновь не быть голословным - пример записи в два потока. Один - временный, только для получения размера, другой - пачка файлов обмена: Условие автора выполнено: пусть с тормозами, но за один проход?
Процедура КнопкаВыполнитьНажатие(Кнопка) // болванка для организации примера работы ЗаписьXML = Новый ЗаписьXML; ИмяФайла = "D:\Temp\Выгрузка_Пачка_"; Пачка = 0; Объектов = 0; ТекРазмер = 0; МаксРазмер = 5000000; //по 5 метров ФайлОткрыт = Ложь; ИмяТемпФайла = ПолучитьИмяВременногоФайла(); FSO = Новый COMОбъект("Scripting.FileSystemObject"); // Будем издеваться над заказами покупателей за текущий год Запрос = Новый Запрос("ВЫБРАТЬ | ЗаказПокупателя.Ссылка |ИЗ | Документ.ЗаказПокупателя КАК ЗаказПокупателя |ГДЕ | ЗаказПокупателя.Проведен = ИСТИНА | И ГОД(ЗаказПокупателя.Дата) = 2009"); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл ОбработкаПрерыванияПользователя(); Объект = Выборка.Ссылка.ПолучитьОбъект(); // Получим размер выгруженного объекта РазмерXML = Новый ЗаписьXML; РазмерXML.ОткрытьФайл(ИмяТемпФайла, "UTF-8"); ЗаписатьXML(РазмерXML, Объект); РазмерXML.Закрыть(); Размер = FSO.GetFile(ИмяТемпФайла).Size; // Какой будет размер пачки, если добавить объект? Не больше максимального? Если ТекРазмер + Размер > МаксРазмер Тогда Если ФайлОткрыт Тогда ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:Data ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:_1CV8DtUD ЗаписьXML.Закрыть(); ФайлОткрыт = Ложь; КонецЕсли; КонецЕсли; // Если выгружаем первый объект в пачку или пачка была ранее закрыта - надо открыть пачку на запись Если Не ФайлОткрыт Тогда Пачка = Пачка + 1; // пишем для совместимости форматов с универсальной обработкой выгрузки/загрузки XML ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл(ИмяФайла + Формат(Пачка,"ЧЦ=3; ЧВН=") + ".xml", "UTF-8"); ЗаписьXML.ЗаписатьОбъявлениеXML(); ЗаписьXML.ЗаписатьНачалоЭлемента("_1CV8DtUD", "http://www.1c.ru/V8/1CV8DtUD/"); ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("V8Exch", "http://www.1c.ru/V8/1CV8DtUD/"); ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance"); ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8", "http://v8.1c.ru/data"); ЗаписьXML.ЗаписатьНачалоЭлемента("V8Exch:Data"); ФайлОткрыт = Истина; ТекРазмер = 0; КонецЕсли; // собственно сама запись объекта ЗаписатьXML(ЗаписьXML, Объект); // Информ-строка дабы юзверу скучно не было :) Объектов = Объектов + 1; ТекРазмер = ТекРазмер + Размер; Состояние("Объектов: " + Объектов +" Пачка: " + Пачка + " Размер: "+ ТекРазмер); КонецЦикла; // Собственно, вот и всё выгружено :) Если ФайлОткрыт Тогда ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:Data ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:_1CV8DtUD ЗаписьXML.Закрыть(); КонецЕсли; Возврат; |
|||
103
TormozIT
гуру
02.10.09
✎
14:33
|
(102) Спасибо за код. Наконец то дал что то пощупать.
Минимальное условие конечно же выполнено. Размер таким способом получается довольно с низкой абсолютной погрешностью. Однако каждый объект сериализуется по 2 раза, что уж слишком увеличивает время. Фактически мы замедляемся в 2 с лишним раза. |
|||
104
asady
02.10.09
✎
14:47
|
(100) кстати твой код тоже раболчий
Процедура КнопкаВыполнитьНажатие(Кнопка) ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьОбъявлениеXML(); ПорогРазмераФайла = 500; ПериодПроверкиРазмераФайла = 5; МассивСтрок=Новый Массив; ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); Для Счетчик = 1 По 12 Цикл ЗаписьXML.ЗаписатьНачалоЭлемента("ББ"); ЗаписьXML.ЗаписатьКонецЭлемента(); Если Счетчик % ПериодПроверкиРазмераФайла = 0 Тогда ЗаписьXML.ЗаписатьКонецЭлемента(); тСтрока = ЗаписьXML.Закрыть(); ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); ЗаписьXML.ЗаписатьБезОбработки(тСтрока); ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); Если СтрДлина(тСтрока) > ПорогРазмераФайла Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; ЗаписьXML.ЗаписатьКонецЭлемента(); Сообщить(ЗаписьXML.Закрыть()); КонецПроцедуры вот так работает. |
|||
105
Wehrmacht
02.10.09
✎
14:52
|
А просто жать файл средствами NTFS (ну т.е. сливать его в сжимаемую папку), например, никак?
|
|||
106
TormozIT
гуру
02.10.09
✎
15:02
|
(104)
ЗаписьXML.ЗаписатьНачалоЭлемента("АА"); <<<<<<<<<<<<<<<<<<<<<<< Если СтрДлина(тСтрока) > ПорогРазмераФайла Тогда Прервать; КонецЕсли; Эта строка отрубает всю универсальность. Нужно восстанавливать все открытые узлы каждый раз. |
|||
107
TormozIT
гуру
02.10.09
✎
15:03
|
(106) Точнее не все, но в обычный формат пакета не получится так писать.
|
|||
108
TormozIT
гуру
02.10.09
✎
15:04
|
Не пойму, почему вверху допускается только один узел блин.
|
|||
109
Serg_1960
02.10.09
✎
15:07
|
(103) Да, тормозим в алгоритме - но не в два раза :( Это ты загнул. Процентов пять теряем, не больше. Может плевать на них? Чай и так не в Формуле-1 выступаем :)
|
|||
110
asady
02.10.09
✎
15:17
|
(108) можно сделать перед
тСтр = ЗаписьXML.Закрыть(); тСтр = СтрЗаменить(тСтр,"</АА><АА>",""); Сообщить(тСтр); |
|||
111
TormozIT
гуру
02.10.09
✎
15:19
|
(110) Не катит. Код должен быть надежным.
|
|||
112
TormozIT
гуру
02.10.09
✎
15:20
|
(109) Маловероятно, что ты прав по поводу 5%. Серьезно.
|
|||
113
Serg_1960
02.10.09
✎
15:30
|
(109) Проверил указанный алгоритм и тоже самое, но без кода для получения размера и проверки на макс размер. Получилось: с записью во временный файл - 81сек. Без проверки размера (простая выгрузка и запись в один файл) - около 78сек. Из первого алгоритма надо еще время отнять на открытие и закрытие файлов пачек...
|
|||
114
Serg_1960
02.10.09
✎
15:36
|
(113) + запрос на первые 2500 документов. Общая выгрузка - чуть более 20 метров.
|
|||
115
TormozIT
гуру
02.10.09
✎
16:33
|
(113) Ладно, Уговорил. Вопрос конечно в том, какая разница будет в наших условиях (которые наверное отличаются от твоих).
Спасибо за помощь и проведенный замер скорости. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |