Convalida / verifica l'integrità dei file PDF


11

Esiste uno strumento che posso eseguire sugli archivi PDF (tutte le directory) e infine elenca / identifica i PDF corrotti / non validi?

Ho centinaia di file PDF (relativi alla documentazione ecc.) Sul mio computer (macchina Windows) e molto spesso ricevo / devo inviare decine di PDF via e-mail. Ora è una normale routine che il PDF che ricevo o invio sia danneggiato. Questo a volte crea seri problemi, quando il file sorgente (ad esempio il file Word o il file Tex è mancante / non disponibile all'istante).

Il controllo di queste migliaia di PDF non è possibile a tempo finito, quindi ho cercato uno strumento che posso eseguire una volta e scansiona tutti i PDF (in directory e sottodirectory), e infine ottengo un elenco di quei file che dovrei ri -creare. Fino ad ora, sembra che non esiste uno strumento del genere.


2
Se sei su Linux prova pdfinfo. Dai un'occhiata a: superuser.com/questions/580887/…
marcwho,


Risposte:


6

È abbastanza facile verificare se un file PDF è valido, usando PDFtk. Una GUI gratuita per PDFtk è disponibile da PDF Labs . Quando esegui questo strumento, puoi caricare tutti i PDF che desideri, da più directory (utilizzando il pulsante Aggiungi file), quindi inizierà ad accedere alle pagine in questi file PDF, molto rapidamente.

Se qualsiasi file tra i PDF selezionati non è un PDF valido, questa utility mostrerà un messaggio sull'errore e lo rimuoverà automaticamente dalla finestra di selezione.

Quindi puoi risparmiare molte ore usando questa procedura con PDFtk. Inoltre, se si dispone di CPU multicore, è possibile eseguire più istanze di questa utility e inserire centinaia di PDF in ciascuna istanza.

Sto usando questo software dall'ultimo anno ed è lo strumento PDF più utile che abbia mai usato.


2
In alternativa, utilizzando lo strumento (pdfinfo.exe) disponibile dal collegamento di cui parla marcwho, è possibile cdin FolderContainingPDFsed eseguire seguente comando nella shell di Windows, e segnerà il file non valido PDF in un file di registro: 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 Shahid

4

Ho usato "pdfinfo.exe" dal pacchetto xpdfbin-win e cpdf.exe per controllare la corruzione dei file PDF, ma non volevo coinvolgere un binario se non fosse necessario.

Ho letto che i formati PDF più recenti hanno un catalogo di dati XML leggibili alla fine, quindi ho aperto il PDF con normali NOTEPAD.exe di Windows e ho scorrere verso il basso i dati illeggibili fino alla fine e ho visto diverse chiavi leggibili. Avevo solo bisogno di una chiave, ma ho scelto di utilizzare sia CreationDate che ModDate.

Il seguente script Powershell (PS) controllerà TUTTI i file PDF nella directory corrente e genererà lo stato di ciascuno in un file di testo (! RESULTS.log). Ci sono voluti circa 2 minuti per eseguire questo su 35.000 file PDF. Ho provato ad aggiungere commenti per coloro che sono nuovi su PS. Spero che questo salvi qualcuno un po 'di tempo. Probabilmente c'è un modo migliore per farlo, ma funziona perfettamente per i miei scopi e gestisce gli errori in silenzio. Potrebbe essere necessario definire quanto segue all'inizio: $ ErrorActionPreference = "SilentlyContinue" se vedi errori sullo schermo.

Copia quanto segue in un file di testo e denominalo in modo appropriato (es: CheckPDF.ps1) o apri PS e naviga nella directory contenente i file PDF per controllarlo e incollarlo nella console.

#
# 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"

3

Seguendo le orme di @n0nuf, ho scritto uno script batch per controllare tutti i PDF in una cartella specifica con pdfinfo e inviarlo tramite cpdf se rotto nel tentativo di risolverli:

@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

O lo stesso dello script 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

I PDF rotti verranno spostati in una sottocartella \ bak e i PDF ricreati ottengono il suffisso _.pdf (che non è perfetto, ma abbastanza buono per me). NOTA: un PDF ricreato contiene errori minori e dovrebbe essere visualizzabile con un normale visualizzatore di PDF. Ma questo non significa che avrai di nuovo tutti i tuoi contenuti. Il contenuto irrecuperabile porta a pagine vuote.

Ho anche provato lo stesso con JHOVE (strumento di identificazione, validazione e caratterizzazione del formato di file open source) come suggerito da @kraftydevil qui: controlla se i file PDF sono danneggiati usando la riga di comando su Linux e ora posso confermare che anche questo è un approccio valido. (Prima ho avuto un successo minore. Ma poi ho notato che non avevo gestito correttamente l'output di JHOVE.)

Per testare entrambi gli approcci ho eliminato e modificato parti casuali da un PDF con un editor di testo (i flussi rimossi, quindi le pagine non sono state visualizzate nel mio visualizzatore PDF, i tag PDF modificati e alcuni bit spostati). Il risultato è: sia pdfinfo che JHOVE sono in grado di individuare correttamente i file danneggiati (in alcuni casi JHOVE era ancora più sensibile).

Ed ecco lo script equivalente per 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


Grazie @Scott. Il ciclo FOR di Windows batch è molto più salvo immagino. Ho fornito l'implementazione dello script bash solo come esempio.
wp78de,

Per sembra essere la strada da percorrere anche per Linux: stackoverflow.com/a/9612232/8291949
wp78de
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.