Проверка / проверка целостности PDF-файлов

11

Есть ли какой-либо инструмент, который я могу запустить в архивах PDF (все каталоги), и, наконец, он перечисляет / идентифицирует поврежденные / недействительные PDF-файлы?

У меня есть сотни файлов PDF (связанных с документацией и т. Д.) На моем компьютере (Windows-машине), и очень часто я получаю / должен посылать десятки PDF-файлов по электронной почте. Теперь это нормальная процедура, когда PDF-файл, который я получаю или отправляю, поврежден. Это иногда создает серьезные проблемы, когда исходный файл (например, файл Word или файл Tex отсутствует / недоступен мгновенно).

Проверка этих тысяч PDF-файлов невозможна за конечное время, поэтому я искал инструмент, который я могу запустить один раз, и он сканирует все PDF-файлы (в каталогах и подкаталогах), и, наконец, я получаю список тех файлов, которые мне следует повторно просмотреть. -Создайте. До сих пор, кажется, нет такого инструмента.

адмирал
источник
2
Если вы используете Linux, попробуйте pdfinfo. Взгляните на: superuser.com/questions/580887/…
marcwho

Ответы:

6

С помощью PDFtk довольно легко проверить, является ли файл PDF действительным. Свободный GUI для Pdftk доступен из PDF Labs . Когда вы запустите этот инструмент, вы можете загрузить столько PDF-файлов, сколько пожелаете, из нескольких каталогов (с помощью кнопки «Добавить файлы»), и тогда он очень быстро начнет получать доступ к страницам в этих файлах PDF.

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

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

Я использую это программное обеспечение с прошлого года, и это самый удобный инструмент PDF, который я когда-либо использовал.

Мубин Шахид
источник
2
Кроме того , с помощью инструмента (pdfinfo.exe) доступен по ссылке упомянутой marcwho, вы можете cdв FolderContainingPDFsи запустить следующую команду в оболочке Windows, и это будет означать недопустимый файл PDF в файл журнала: FORFILES /S /M *.pdf /C "cmd /c echo. & echo @path @fname & D:\XPDF_3.04\bin64\pdfinfo.exe @file" 1>text.txt 2>&1
Mubeen Шахид
4

Я использовал «pdfinfo.exe» из пакета xpdfbin-win и cpdf.exe для проверки файлов PDF на наличие повреждений, но не хотел использовать двоичный файл, если в этом нет необходимости.

Я прочитал, что в новых форматах PDF в конце есть читаемый каталог данных xml, поэтому я открыл PDF с обычными окнами NOTEPAD.exe и прокрутил до конца нечитаемые данные и увидел несколько читаемых ключей. Мне нужен был только один ключ, но я решил использовать и CreationDate, и ModDate.

Следующий скрипт Powershell (PS) проверит ВСЕ PDF-файлы в текущем каталоге и выведет их состояние в текстовый файл (! RESULTS.log). Потребовалось около 2 минут, чтобы запустить это с 35 000 PDF-файлов. Я попытался добавить комментарии для тех, кто плохо знаком с PS. Надеюсь, это сэкономит кому-то время. Вероятно, есть лучший способ сделать это, но это работает безупречно для моих целей и обрабатывает ошибки бесшумно. В начале вам может потребоваться определить следующее: $ ErrorActionPreference = "SilentlyContinue", если вы видите ошибки на экране.

Скопируйте следующее в текстовый файл и назовите его соответствующим образом (например, CheckPDF.ps1) или откройте PS и перейдите в каталог, содержащий файлы PDF, чтобы проверить и вставить его в консоль.

#
# PowerShell v4.0
#
# Get all PDF files in current directory
#
$items = Get-ChildItem | Where-Object {$_.Extension -eq ".pdf"}

$logFile = "!RESULTS.log"
$badCounter = 0
$goodCounter = 0
$msg = "`n`nProcessing " + $items.count + " files... "
Write-Host -nonewline -foregroundcolor Yellow $msg
foreach ($item in $items)
{
    #
    # Suppress error messages
    #
    trap { Write-Output "Error trapped"; continue; }

    #
    # Read raw PDF data
    #
    $pdfText = Get-Content $item -raw

    #
    # Find string (near end of PDF file), if BAD file, ptr will be undefined or 0
    #
    $ptr1 = $pdfText.IndexOf("CreationDate")
    $ptr2 = $pdfText.IndexOf("ModDate")

    #
    # Grab raw dates from file - will ERR if ptr is 0
    #
    try { $cDate = $pdfText.SubString($ptr1, 37); $mDate = $pdfText.SubString($ptr2, 31); }

    #
    # Append filename and bad status to logfile and increment a counter
    # catch block is also where you would rename, move, or delete bad files.
    #
    catch { "*** $item is Broken ***" >> $logFile; $badCounter += 1; continue; }

    #
    # Append filename and good status to logfile
    #
    Write-Output "$item - OK" -EA "Stop" >> $logFile

    #
    # Increment a counter
    #
    $goodCounter += 1
}
#
# Calculate total
#
$totalCounter = $badCounter + $goodCounter

#
# Append 3 blank lines to end of logfile
#
1..3 | %{ Write-Output "" >> $logFile }

#
# Append statistics to end of logfile
#
Write-Output "Total: $totalCounter / BAD: $badCounter / GOOD: $goodCounter" >> $logFile
Write-Output "DONE!`n`n"
n0nuf
источник
3

Следуя указаниям @ n0nuf, я написал пакетный скрипт, чтобы проверить все PDF-файлы в определенной папке с помощью pdfinfo и протолкнуть его через cpdf, если он был сломан, в попытке их исправить:

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    pdfinfo "%%f" 2>&1 | findstr /I "error"  >nul 2>&1
    if not errorlevel 1 (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        mv %%f .\\bak\\%%f
    ) else (
       REM echo good        
    )
)
@ECHO ON

Или так же, как скрипт bash:

for file in $(find . -iname "*.pdf")
do
    echo "$file"
    pdfinfo "$file" 2>&1 | grep -i 'error' &> /dev/null
    if [ $? == 0 ]; then
       echo "broken -> try to fix"
       cpdf -i "$file" -o "$file"_.pdf
    fi
done

Сломанные PDF-файлы будут перемещены в подпапку \ bak, а воссозданные PDF-файлы получат суффикс _.pdf (который не идеален, но достаточно хорош для меня). ПРИМЕЧАНИЕ. Повторно созданный PDF-файл содержит меньше ошибок и должен просматриваться с помощью обычного средства просмотра PDF-файлов. Но это не значит, что вы получите весь свой контент обратно. Невосстанавливаемый контент приводит к пустым страницам.

Я также попробовал то же самое с JHOVE (инструмент для идентификации, проверки и определения формата файла с открытым исходным кодом), как предложено здесь @kraftydevil: Проверьте, не повреждены ли PDF-файлы с помощью командной строки в Linux, и теперь можно подтвердить, что это также правильный подход. (Сначала у меня был меньший успех. Но потом я заметил, что неправильно обработал вывод JHOVE.)

Чтобы протестировать оба подхода, я удалил и изменил случайные части из PDF с помощью текстового редактора (удалял потоки, поэтому страницы не отображались в моей программе просмотра PDF, изменял теги PDF и сдвигал некоторые биты). Результат: и pdfinfo, и JHOVE способны правильно определять поврежденные файлы (в некоторых случаях JHOVE был еще более чувствительным).

А вот эквивалентный скрипт для JHOVE:

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    "C:\Program Files (x86)\JHOVE\jhove.bat" -m pdf-hul %%f | findstr /C:"Well-Formed and valid" >nul 2>&1
    if not errorlevel 1 (
        echo good
    ) else (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        REM mv %%f .\\bak\\%%f
    )
)
@ECHO ON
wp78de
источник
Спасибо @ Скотт. Я полагаю, что Windows-цикл FOR для Windows намного более экономичен. Я дал реализацию скрипта bash просто в качестве примера.
wp78de
Ибо похоже, что Linux тоже подходит для этого: stackoverflow.com/a/9612232/8291949
wp78de