Читать бинарный файл в java до определенного маркера "%% EOF"? - PullRequest
0 голосов
/ 04 сентября 2018

Мне нужно прочитать двоичный файл в java и разделить его (на самом деле это двоичный файл, содержащий много файлов pdf, с одной строкой «метаданные» перед каждым).

Каждый элемент PDF из двоичного файла заканчивается маркером "%%EOF".

Моя первая попытка, я построчно считывал файл как файл UTF-8, но это повредило двоичные данные !!

reader = new BufferedReader(new InputStreamReader(new FileInputStream(binaryFile), "UTF-8"));

String mdmeta;
while ((mdmeta = reader.readLine()) != null) {
    System.out.println("read file metadata: " + mdmeta);
    writeToFile("exploded-file-123");
}

и метод writeToFile

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fullFilename), "UTF-8"));

writer.write("%PDF-1.4\r\n");
String line;
while ((line = reader.readLine()) != null) {
    writer.write(line);
    writer.write("\r\n");
    if ("%%EOF".equals(line)) {
        writer.flush();
        return;
    }
}

... хотя это разбивает файл на разобранные элементы, эти двоичные файлы повреждены (конечно, потому что я читал и записывал байты как UTF-8 строки ...)

Я думаю, что мне нужен более низкоуровневый подход с использованием InputStream's.

Это становится сложным, поскольку файлы могут быть большими. Представьте, что я использую буфер ... Я могу прочитать байты из файла, чтобы заполнить буфер ... тогда мне нужно найти "%%EOF" внутри буфера ... и вручную разделить буфер между предыдущим разобранным элементом и следующий.

Или, если "%%EOF" упадет на край буфера, тогда я могу полностью пропустить границу файла ...

Полагаю, я ищу какой-то путь к readBytesUpUntil("%%EOF") - есть ли простой способ сделать это?

1 Ответ

0 голосов
/ 04 сентября 2018

Просмотрщики PDF начинают читать файл в конце. Они ищут %%EOF, а затем начало таблицы xref или таблицу перекрестных ссылок. Таблица перекрестных ссылок сопоставляет все объекты со смещением в байтах.

Например:

  • объект с номером 1 начинается в байтовой позиции 12578
  • объект с номером 2 начинается в байтовой позиции 158
  • объект с номером 3 начинается в байтовой позиции 9821
  • объект с номером 4 начинается в байтовой позиции 18792
  • ...

и т. Д.

Средство просмотра PDF также ищет номер объекта /Catalog или корневого словаря документа PDF. Он ищет объект /Catalog путем перехода к байтовому смещению, как указано в таблице перекрестных ссылок.

Из этого корневого словаря программа просмотра PDF получает корень дерева /Pages. Из дерева /Pages он получает информацию о страницах в PDF, включая информацию о том, где найти весь контент и ресурсы, необходимые для отображения страницы.

Все это происходит посредством произвольного доступа к файлу со смещением байтов, полученным из таблицы перекрестных ссылок на основе номеров объектов.

Сейчас:

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

Кроме того, PDF может содержать более одного %%EOF маркера. Это в случае с линеаризованным PDF, и в случае с PDF, которые были постепенно обновлены.

Такие PDF-файлы также должны быть прочитаны, начиная с последнего байта. В таблице перекрестных ссылок последней ревизии будут заменены некоторые существующие объекты и добавлены новые объекты, но вам все равно понадобится таблица перекрестных ссылок предыдущих ревизий, в противном случае вы ничего не сможете отрендерить.

Сейчас:

  • Представьте, что вы разбили бы файл, который постепенно обновляется в зависимости от появления %%EOF,
  • Представьте, что вы сохраните каждый из этих фрагментов в отдельный файл,
  • Тогда только первый файл будет действительным файлом PDF; во всех последовательных файлах будут отсутствовать ресурсы, такие как шрифты, повторно используемые изображения и т. д. Последовательные файлы не будут полными документами PDF.

Короче говоря:

Разделять длинный документ PDF на основании появления %%EOF нецелесообразно. Даже если ряд действительных PDF-файлов склеены, вы рискуете разбить эти файлы, поскольку один и тот же PDF-файл может иметь несколько экземпляров %%EOF.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...