J'ai une application Windows .NET qui gère de nombreux PDF fichiers. Certains fichiers sont corrompus.
2 questions: je vais essayer d'expliquer dans mon pire anglais ... désolé
1.)
Comment puis-je détecter si un fichier PDF est correct?
Je veux lire l'en-tête de PDF et détecter est correct.
var okPDF = PDFCorrect (@ "C:\temp\pdfile1.pdf");
2.)
Comment savoir si l'octet [] (bytearray) du fichier est un fichier PDF ou non.
Par exemple, pour les fichiers Zip, vous pouvez examiner les quatre premiers octets et voir s’ils correspondent à la signature de l’en-tête local, c’est-à-dire en hexadécimal.
50 4b 03 04
if (tampon [0] == 0x50 && tampon [1] == 0x4b && tampon [2] == 0x03 && tampon [3] == 0x04)
Si vous le chargez longuement, il s’agit de (0x04034b50). par David Pierson
Je veux la même chose pour les fichiers PDF.
octet [] dataPDF = ...
var okPDF = PDFCorrect (dataPDF);
Un exemple de code source dans .NET?
1) Malheureusement, il n’existe aucun moyen facile de déterminer si un fichier pdf est corrompu. En général, les fichiers problématiques ont un en-tête correct. Les véritables raisons de la corruption sont donc différentes. Le fichier PDF est en réalité un vidage d'objets PDF. Le fichier contient une table de référence donnant les emplacements exacts de décalage d'octet de chaque objet à partir du début du fichier. Donc, la plupart des fichiers corrompus ont probablement des décalages brisés ou un objet est manquant.
Le meilleur moyen de déterminer si le fichier est corrompu consiste à utiliser les bibliothèques spécialisées PDF. Il existe de nombreuses bibliothèques gratuites et commerciales pour .NET. Vous pouvez simplement essayer de charger le fichier PDF avec l’une de ces bibliothèques. iTextSharp sera un bon choix.
2) Conformément à PDF référence, l'en-tête du fichier PDF se présente généralement sous la forme% PDF − 1.X (où X est un nombre, pour le moment, de 0 à 7). Et 99% des fichiers PDF ont un tel en-tête. Mais il existe également d’autres types d’en-têtes acceptés par Acrobat Viewer et même l’absence d’en-tête n’est pas un réel problème pour les lecteurs PDF. Donc, vous ne devriez pas traiter le fichier comme corrompu s'il n'a pas d'en-tête. E.g. l'en-tête peut apparaître quelque part dans les 1024 premiers octets du fichier ou être sous la forme%! PS − Adobe − N.n PDF − M.m
Juste pour votre information, je suis un développeur de la Docotic PDF library .
Je vérifie l'en-tête PDF comme ceci:
public bool IsPDFHeader(string fileName)
{
byte[] buffer = null;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(fileName).Length;
//buffer = br.ReadBytes((int)numBytes);
buffer = br.ReadBytes(5);
var enc = new ASCIIEncoding();
var header = enc.GetString(buffer);
//%PDF−1.0
// If you are loading it into a long, this is (0x04034b50).
if (buffer[0] == 0x25 && buffer[1] == 0x50
&& buffer[2] == 0x44 && buffer[3] == 0x46)
{
return header.StartsWith("%PDF-");
}
return false;
}
La première ligne d'un fichier PDF est un en-tête identifiant la version de la spécification PDF à laquelle le fichier est conforme %PDF-1.0
, %PDF-1.1
, %PDF-1.2
, %PDF-1.3
, %PDF-1.4
, etc.
Vous pouvez vérifier cela en lisant quelques octets depuis le début du fichier et voir si vous avez l'en-tête au début pour une correspondance en tant que fichier PDF. Voir le PDF référence d’Adobe pour plus de détails.
Vous n'avez pas d'exemple .NET pour vous (je n'ai pas touché la question depuis quelques années maintenant), mais même si j'en avais, je ne suis pas sûr que vous puissiez vérifier le contenu complet du fichier. L'en-tête peut être OK mais le reste du fichier peut être gâché (comme vous l'avez dit vous-même, certains fichiers sont corrompus).
Les PDF bien agencés commencent par les 9 premiers octets sous la forme %PDF-1.x
plus une nouvelle ligne (où x dans 0..8). 1.x
est censé vous donner la version du format de fichier PDF. La deuxième ligne contient des octets binaires afin d’aider les applications (éditeurs) à identifier le PDF en tant que type de fichier non ASCIItext.
Cependant, vous ne pouvez pas du tout faire confiance à cette balise. De nombreuses applications utilisent les fonctionnalités de PDF-1.7, mais prétendent être PDF-1.4 et induisent donc en erreur certains téléspectateurs en crachant des messages d'erreur non valides. (La plupart d'entre eux, ces PDF sont le résultat d'une conversion mal gérée du fichier d'une version supérieure à une version inférieure PDF.)
Il n’existe pas de section comme "en-tête" dans PDF (peut-être que les 9 octets initiaux de %PDF-1.x
correspondent à ce que vous vouliez dire par "en-tête"?). Il peut y avoir une structure incorporée pour conserver les métadonnées dans le PDF, qui vous donne des informations sur Author, CreationDate, ModDate, Title et quelques autres éléments.
Il n’existe aucun autre moyen de vérifier la validité et la non-corruption d’un PDF que de le restituer.
Un moyen "peu coûteux" et plutôt fiable de vérifier cette validité pour moi personnellement consiste à utiliser Ghostscript .
Cependant: vous voulez que cela se produise rapidement et automatiquement. Et vous souhaitez utiliser la méthode par programme ou via une approche scriptée pour vérifier de nombreux PDF.
Voici le truc:
nullpage
de Ghostscript.Voici un exemple de ligne de commande:
gswin32c.exe ^
-o nul ^
-sDEVICE=nullpage ^
-r36x36 ^
"c:/path to /input.pdf"
Cet exemple est pour Windows; sous Unix, utilisez gs
au lieu de gswin32c.exe
et -o /dev/null
.
Utiliser -o nul -sDEVICE=nullpage
ne produira aucun résultat de rendu. Mais toutes les sorties stderr et stdout du traitement du fichier input.pdf par Ghostscript apparaîtront toujours dans votre console. -r36x36
définit la résolution sur 36 dpi pour accélérer le contrôle.
%errorlevel%
(ou $?
sous Linux) sera 0
pour un fichier non corrompu. Ce sera non -0
pour les fichiers corrompus. Et tous les messages d’avertissement ou d’erreur apparaissant sur stdout peuvent vous aider à identifier les problèmes liés à input.pdf.
Il n'y a pas d'autre moyen de vérifier la corruption d'un fichier PDF que de le rendre en quelque sorte ...
Mise à jour: Pendant ce temps, pas seulement% PDF-1.0,% PDF-1.1,% PDF-1.2,% PDF-1.3,% PDF-1.4,% PDF-1.5,% PDF-1.6,% PDF-1.7 et% PDF-1.8 sont des indicateurs de version valides,mais aussi% PDF-2.0.
Vérifier l'en-tête est délicat. Une partie du code ci-dessus ne fonctionnera tout simplement pas, car tous les PDF ne commencent pas par% PDF. Certains pdf qui s'ouvrent correctement dans un visualiseur commencent par un marqueur de nomenclature, d'autres commencent comme ceci
------------ e56a47d13b73819f84d36ee6a94183 Contenu-Disposition: données de formulaire; name = "par" ... etc
Donc, vérifier "% PDF" ne fonctionnera pas.
Vous pouvez utiliser iTextSharp pour ouvrir et tenter d’analyser le fichier (par exemple, essayer d’en extraire du texte), mais c’est probablement excessif. Vous devez également savoir qu'il s'agit de GNU Affero GPL , sauf si vous achetez une licence commerciale.
Ce que je fais c'est:
1.Valider l'extension
2.Ouvrez le fichier PDF, lisez l'en-tête (première ligne) et vérifiez s'il contient la chaîne suivante: "% PDF-"
3.Vérifiez si le fichier contient une chaîne spécifiant le nombre de pages en recherchant plusieurs "/ page" (le fichier PDF doit toujours comporter au moins une page)
Comme suggéré précédemment, vous pouvez également utiliser une bibliothèque pour lire le fichier: Lecture PDF Fichier à l'aide de iTextSharp