Valider / vérifier l'intégrité des fichiers PDF

Y at-il un outil que je peux exécuter sur les archives PDF (tous les répertoires) et enfin, il liste / identifie les fichiers PDF corrompus / invalides?

J'ai des centaines de fichiers PDF (liés à la documentation, etc.) sur mon ordinateur (machine Windows), et très souvent, je reçois / je dois envoyer des dizaines de fichiers PDF par courrier électronique. C'est maintenant une routine normale que le PDF que je reçois ou envoie est corrompu. Cela crée des problèmes sérieux parfois, lorsque le fichier source (par exemple, le fichier Word ou le fichier Tex manque / n'est pas disponible instantanément).

La vérification de ces milliers de fichiers PDF n'est pas possible en temps partiel, alors j'ai cherché un outil que je peux exécuter une fois et il scanne tous les fichiers PDF (dans les répertoires et les sous-répertoires), et enfin je reçois une liste de ces fichiers que je devrais -créer. Jusqu'à présent, il semble qu'il n'y ait pas un tel outil.

Il est assez facile de vérifier si un fichier PDF est valide, en utilisant PDFtk. Une interface graphique gratuite pour PDFtk est disponible auprès de PDF Labs . Lorsque vous exécutez cet outil, vous pouvez charger autant de fichiers PDF que vous le souhaitez, à partir de plusieurs répertoires (en utilisant le bouton Ajouter des fichiers), puis il va commencer à accéder aux pages de ces fichiers PDF très rapidement.

Si un fichier parmi les fichiers PDF sélectionnés n'est pas un PDF valide, cet utilitaire affichera un message sur l'erreur et l'éliminera automatiquement de la fenêtre de sélection.

Par conséquent, vous pouvez économiser de nombreuses heures en utilisant cette procédure avec PDFtk. En outre, si vous disposez d'une CPU multicœur, vous pouvez exécuter plusieurs instances de cet utilitaire et jeter des centaines de fichiers PDF dans chaque instance.

J'utilise ce logiciel depuis un an, et c'est l'outil PDF le plus pratique que j'ai jamais utilisé.

J'ai utilisé "pdfinfo.exe" du package xpdfbin-win et cpdf.exe pour vérifier les fichiers PDF pour corruption, mais je ne voulais pas impliquer un binaire si ce n'était pas nécessaire.

J'ai lu que les nouveaux formats PDF possèdent un catalogue de données xml lisible à la fin, j'ai donc ouvert le fichier PDF avec normalement Windows NOTEPAD.exe et défilé après les données illisibles jusqu'à la fin et j'ai vu plusieurs clés lisibles. J'ai seulement besoin d'une clé, mais j'ai choisi d'utiliser CreationDate et ModDate.

Le script Powershell (PS) suivant vérifie TOUS les fichiers PDF dans le répertoire actuel et affiche l'état de chacun dans un fichier texte (! RESULTS.log). Il a fallu environ 2 minutes pour exécuter ceci contre 35 000 fichiers PDF. J'ai essayé d'ajouter des commentaires pour ceux qui sont nouveaux dans PS. J'espère que cela sauve quelqu'un quelque temps. Il y a probablement une meilleure façon de le faire, mais cela fonctionne parfaitement pour mes besoins et gère les erreurs en silence. Vous devrez peut-être définir ce qui suit au début: $ ErrorActionPreference = "SilentlyContinue" si vous voyez des erreurs sur l'écran.

Copiez ce qui suit dans un fichier texte et nommez-le de manière appropriée (ex: CheckPDF.ps1) ou ouvrez PS et parcourez le répertoire contenant les fichiers PDF pour le vérifier et le coller dans la 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" 

En suivant les pas de @n0nuf, j'ai écrit un script de lot pour vérifier tous les fichiers PDF dans un dossier spécifique avec pdfinfo et le faire passer par cpdf si cassé comme tentative de les réparer:

 @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 

Ou le même que le 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 

Les PDF brisés seront déplacés vers un sous-dossier \ bak et les PDF recréés obtiennent le suffixe _.pdf (ce qui n'est pas parfait, mais assez bon pour moi). REMARQUE: un PDF recréé contient des erreurs moindres et devrait être visible avec un visualiseur PDF régulier. Mais cela ne signifie pas que vous récupérez tout votre contenu. Le contenu irrécupérable conduit à des pages vides.

J'ai également essayé la même chose avec JHOVE (outil d'identification, de validation et de caractérisation du format de fichier source), tel que suggéré par @kraftydevil ici: Vérifiez si les fichiers PDF sont corrompus à l'aide de la ligne de commande sur Linux et peuvent maintenant confirmer que ceci est également une approche valide. (D'abord, j'ai eu moins de succès. Mais j'ai remarqué que je n'avais pas correctement traité la sortie de JHOVE.)

Pour tester les deux approches, j'ai supprimé et modifié des parties aléatoires à partir d'un fichier PDF avec un éditeur de texte (flux supprimés, donc les pages n'ont pas été rendues dans mon visualiseur PDF, modifications de balises PDF et déplacé certains bits). Le résultat est: Pdfinfo et JHOVE peuvent repérer les fichiers endommagés correctement (JHOVE était encore plus sensible dans certains cas).

Et voici le script équivalent pour 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 

Il existe une différence entre le type de fichier "non valide PDF" et un fichier PDF corrompu. Je viens de corriger un fichier PDF corrompu via pdftk et il ne l'a pas détecté.

Jusqu'à présent, pdf2ps (un outil ghostscript) détecte mieux les fichiers corrompus, mais je ne sais pas si les pdfs créés sur les Mac sont correctement évalués.