То есть вы также готовы рассмотреть других клиентов?Похоже, у вас есть приложение для рисования для детей, и вы хотите сгенерировать что-то, что сохранит состояние их рисунка на данный момент.
Посмотрим правде в глаза, XML не так эффективен.Это не его цель.Он может быть читаем как на компьютере, так и на человеке, проверяется и т. Д. И т. Д.
Вместо этого, как насчет веб-страницы на основе <Canvas>
, которая отправляла состояние этого холста на сервер в JSON (меньше байтов и меньше работы для сборки)их).Сервер может тогда работать на любой адской библиотеке / языке, который он хочет.Множество библиотек JSON-> my-language.
Ваш выбор в библиотеках PDF будет ограничен только тем, что установлено на вашем сервере.Вы также сказали, что хотите сделать как можно меньше чтения / записи.
Наиболее эффективной из возможных настроек будет иметь частичный PDF-файл только для чтения, уже загруженный в память с учетом минимальных последствий изменений холста (включаяизображений).Каждый сеанс будет дублировать этот частичный PDF, преобразовывать графические команды JSON в PDF и сохранять PDF.
Чтобы минимизировать структурные изменения в PDF, вам необходимо использовать встроенные изображения.Отсутствие новых объектов в PDF означает, что вам вообще не нужно менять таблицу перекрестных ссылок (пока вы не добавите шрифты или не захотите повторно использовать существующее изображение).Вы могли бы создать словарь "информация о документе", дополненный определенным количеством пробелов между объектами, чтобы вы могли заполнить его, не изменяя смещения байтов (что заставило бы вас пересчитывать таблицу внешних ссылок).
Вы можете илиможет не нужно возиться с размером страницы ... мы просто говорим здесь об одной странице, верно?
Так что PDF будет выглядеть примерно так ...
%%PDF-1.6
<3-4 random high order bytes to convince folks that we're a binary stream>
1 0 obj
<</Type/Catalog/Pages 2 0 R>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[3 0 R]>>
endobj
3 0 obj
<</Type/Page/Contents 4 0 R/MediaBox[0 0 612 792]/Parent 2 0 R>>
endobj
5 0 obj
<</Type/DocInfo/Author() --<insert big whitespace gap here>--
/Title() --<ditto>--
/Subject() --<ditto>--
/Keywords() --<ditto>--
/Creator(My app's Name)
/Producer(My pdf library's name)
/CreationDate(encodedDateWhenThisTemplateWasBuilt) D:YYYYMMDDHHMMSS-timeZoneOffset
/ModDate() --<another, smaller whitespace gap>--
>>
4 0 obj
<</Filter/SeveralDifferentFiltersAvailable/Length --<byte length of the stream in this file>-->>
stream
И вашШаблон останавливается там.У вас будет похожий шаблон «конец PDF», который будет выглядеть примерно так:
endstream
endobj
xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000025 00000 n
0000000039 00000 n
0000000097 00000 n
0000000050 00000 n
trailer
<</Root 1 0 R/Size 6/Info 5 0 R>>
startxref
--<some white space>--
%%EOF
Столбцы чисел в конце неверны.Первый столбец - это смещение в байтах этого конкретного объекта (и я не собираюсь считать байты только сейчас, спасибо).Второй столбец в значительной степени не имеет значения.
Приложение для заполнения PDF должно знать:
- Смещение байтов всего, что вы намереваетесь заполнить в первом шаблоне.
- Все поля «doc info», которые, кстати, не являются обязательными.Ключ / Info и словарь, на который он указывает, являются необязательными в этом отношении.Вы можете дернуть их, если хотите.
- ключ / Length потока контента.Это должна быть длина байта пост-фильтра самого потока.
- Как преобразовать JSON в команды рисования pdf.Если вы хотите немного обмануть, вы можете использовать класс PdfContentByte iText [Sharp], использовать его команды рисования, а затем получить готовый поток байтов и вставить его в свой PDF.Убедитесь, что вы используете встроенные изображения или вся эта схема идет прямо в окно.Возможно, есть и другие библиотеки, которые вы могли бы аналогичным образом обработать, если бы почувствовали необходимость.Или вы можете просто прочитать спецификации PDF и свернуть свои собственные.Вы будете придерживаться довольно ограниченного подмножества синтаксиса содержимого PDF.
- Смещение в байтах слова "xref" от начала файла.Вы можете рассчитать это: LengthOfInitialTemplate + LengthOfContentStream + OffsetFromStartOf2ndTemplateTo'xref '.
- Смещение в байтах строки ниже «startxref», где вы пишете выше вычисленное смещение байтов «xref»
Вы не станете намного эффективнее этого.Вы бы прочитали в своих шаблонах один раз.Считайте / рассчитайте смещение байтов, которое вам нужно один раз.