2014-11-06 1 views
0

Если я получаю доступ к PDF-файлу, чтобы добавить что-то в настраиваемое свойство, используя код Файл src_2 = new File (embed_source); Файл dest_2 = новый файл (embed_destination_2);При изменении PDF-файла и последующем удалении изменения хэши восстановленного файла и исходного файла различаются

    try { 
         FileUtils.copyFile(src_2, dest_2); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        }   
public void manipulatePdf(String src, String dest) throws IOException, DocumentException { 
      PdfReader reader = new PdfReader(src); 
      PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
      Map<String, String> info = reader.getInfo(); 
      System.out.println(info.get("Lala")); 

      stamper.setMoreInfo((HashMap<String, String>) info); 
      stamper.close(); 
      reader.close(); 
     } 

Я ничего не изменить в файле Src, что я сделал это только, чтобы получить какую-то информацию о файле Src. Тем не менее, у меня есть два разных хэш-результата из файла src до и после запуска программы. Могу я узнать почему?

ответ

1

Если вы читаете ISO-32000-1, вы должны знать, что два PDF-файла не равны по дизайну. Одним из наиболее типичных различий между двумя PDF-файлов является идентификатором:

От ISO-32000-1:

ID: Массив из двух байт-строк, составляющих идентификатор файла.

Из раздела 14.4, озаглавленный «идентификаторы файлов»:

Значения этой записи должны быть массивом из двух строк байт. Первая строка байта должна быть постоянным идентификатором на основе содержимого файла в момент его первоначального создания и не должна изменяться при постепенном обновлении файла. Вторая строка байта должна быть изменением идентификатора на основе содержимого файла в момент его последнего обновления. Когда файл сначала записывается, оба идентификатора должны быть одинаковыми. Если оба идентификатора совпадают, когда ссылка на файл решена, очень вероятно, что найден правильный и неизменный файл. Если совпадает только первый идентификатор, была найдена другая версия правильного файла.

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

Примечание. Существует не так много инструментов, которые создают PDF-файлы, идентификаторы которых идентичны. Это потому, что PDF, созданный с нуля, обычно обрабатывается до того, как окончательная версия будет сохранена на диске. Просто создайте PDF, используя Adobe Acrobat, чтобы воспроизвести это: вы заметите, что пара идентификаторов состоит из двух разных значений. Это делает бесполезным спросить: мы можем создать ситуацию, когда второй идентификатор идентичен первому?

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

Как решить эту проблему?

Вы тот человек, который задал этот вопрос [как] Add/delete/retrieve information from a PDF using a custom property

В моем ответе на этот вопрос, я объясню, как добавить метаданные к существующему PDF:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 

Это создает новый PDF-файл, в котором объекты переупорядочиваются.

Однако, вы можете изменить эту строку в:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest), '\0', true); 

Теперь вы создаете инкрементного обновления вашего файла PDF.

Что такое постепенное обновление?

Предположим, что ваш оригинальный PDF файл выглядит следующим образом:

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 

При использовании IText манипулировать такой файл, вы получите измененный PDF файл:

%PDF-1.4 
% plenty of altered PDF objects and altered PDF syntax 
%%EOF 

Во время этого процесса объекты могут быть перенумерованы, реорганизованы и т. Д. Если вы добавите что-то в первый раз и удалите что-то во второй раз, вы можете ожидать, что PDF l ooks то же самое для человеческого глаза при открытии документа в программе просмотра PDF, но вы не должны ожидать, что синтаксис PDF будет идентичным. Это предположение выявило бы полное отсутствие понимания в формате PDF.

Однако при использовании PdfStamper в режиме дописывания выполнить постепенное обновление, вы получите пошагово обновленный PDF:

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 
% updates for PDF objects and PDF syntax 
%%EOF 

В этом случае исходные байты исходного PDF Арен» t изменено. Размер файла становится больше, потому что теперь у вас будет некоторая избыточная информация (некоторые объекты больше не будут использоваться, из некоторых объектов у вас будет старая версия вместе с новой версией), но преимущество использования инкрементного обновления заключается в том, что вы всегда можете вернуться к исходному файлу.

Это достаточно для поиска второго последнего появления %%EOF и удалить все байты, которые следуют, вы получите усеченного PDF файл:

%PDF-1.4 
% plenty of PDF objects and PDF syntax 
%%EOF 

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

Предостережение: Остерегайтесь пробельных символов, которые следует за %%EOF. Они могут вызывать минимальную разницу на уровне байтов, что заставляет хеши быть разными.

+0

Большое спасибо! Это действительно полезно – brian

+0

Да, когда я ответил в комментарии, я не думал об инкрементальных обновлениях.Обычно идеи начинают наступать, когда я пишу реальный ответ. Вот почему разработчики, задающие вопросы по StackOverflow, должны создавать новые вопросы, а не использовать раздел комментариев. Я говорю это в общем: я не хочу критиковать конкретных людей ;-) –

+0

Получил! еще раз спасибо – brian

Смежные вопросы