Forum Programmation.php Récupérer les enregistrements d'un fichier...

Posté par  .
Étiquettes : aucune
0
2
mar.
2006
Hello !
J'ai un fichier binaire, dans lequel, je trouve à la fin ceci :


trailer
<<
/Size 277
/Root 275 0 R
/Info 276 0 R
>>
startxref
405355
%%EOF


Tout ça ne m'intéresse pas. Je ne veux que le nombre sur la ligne précédant le "%%EOF", ainsi que le nombre situé après le /Info.
J'essaye de bidouiller php pour obtenir ces informations le plus rapidement possible, car c'est pour le web, et il ne faut pas que le traitement soit trop long sous peine de time-out.
Je cherche donc comment parvenir à mes fins, mais pour l'instant je ne suis que moyennement satisfait. Voici donc les questions que je me pose :
- est-ce que lire le fichier ligne par ligne du début à la fin semble une bonne idée ? Je ne pense pas, mais sait-on jamais.
- Est-ce que me placer à la fin, et faire reculer le pointeur sur le fichier à coup de fseek ($fp, $offset--, SEEK_END) jusqu'à trouver le 'f' de startxref - ou le 2nd retour à la ligne - grâce à fgetc serait plus performant ?
- Existe-t-il une méthode à laquelle je n'aurais pas pensé qui me ferait gagner mon temps ?
- Avez-vous d'autres avis sur la question ?
- Pierre Tramo ?
Le problème, c'est que le nombre précédant le %%EOF n'est évidement jamais le même, ainsi que le nombre derrière le /Info.
Merci pour votre aide/vos conseils...
S je trouve quelque chose qui me semble pertinent dans l'intervalle, je posterais ma solution ci-dessous.
  • # Librairie toute faite ?

    Posté par  . Évalué à 2.

    Hello,

    Avant de réinventer la route (même si j'aime le faire parfois, ou sauf si évidemment ton cas est très particulier), n'y a t'il pas des librairies toutes faites pour la manipulation des PDF en PHP te permettant de récupérer les infos que tu veux ?
    • [^] # Re: Librairie toute faite ?

      Posté par  . Évalué à 2.

      En effet, il en existe certainement.
      Le problème n'est pas pour ma machine, sur laquelle j'installe ce que je veux, mais les machines sur lesquelles je déploie mes softs : sur ces dernières, pas moyen d'installer quoi que ce soit.
      J'aurais pu faire tout simple :
      system ("pdfinfo fichier.pdf"); fait exactement ce que je veux, mais maintenant, tu sais pourquoi je veux recoder ça "from scratch"...
  • # Regexp ??

    Posté par  . Évalué à 1.

    et pourquoi tu utiliserais pas un regexp avec un preg_match() http://fr.php.net/manual/fr/function.preg-match.php ??

    tu choperai sans probleme le chiffre derriere /info et celui avant le EOF.
  • # Bon, ben voilà...

    Posté par  . Évalué à 2.

    J'ai cherché, et j'ai trouvé ;-) !
    Ou plutôt, j'ai codé et j'ai trouvé.
    Je joins le code, si ça en intéresse d'autres tant mieux !
    Si vous trouvez ça gruick, tant mieux !
    Si vous avez mieux à proposer, tant mieux !
    Bref, je suis ouvert à toute critique de ce code, pourvu qu'elle soit constructive.

    function getInfos ($filename)
    {
    $nlcount=0;
    $fp = fopen ($filename, "rb");
    $taille = 0;
    while ($nlcount<3) // On passe les 2 derniers retours à la ligne
    {
    fseek ($fp, --$taille, SEEK_END);
    $c = fgetc($fp);
    if ($c == "\n") $nlcount++;
    }
    $offsetXref = fgets ($fp); // On récupère l'offset de l'objet xref
    fseek ($fp, $taille, SEEK_END);
    while ( ! preg_match ("/(\/Info)/", $buf)) // On recherche la chaîne /Info
    {
    while (fgetc($fp) != "\n")
    fseek ($fp, --$taille, SEEK_END);
    $buf = fgets ($fp);
    fseek ($fp, --$taille, SEEK_END);
    }
    $buf = preg_replace ('/(.*)(\/Info.*)/', '\\2', $buf); // On récupère le numéro de l'objet info dans le fichier pdf (2nd champs).
    $tmp = explode (' ', $buf);
    $objectNumber = $tmp[1];
    // close the file
    fseek ($fp, $offsetXref);
    while ($currObject < $objectNumber) // On parcours l'objet xref
    {
    $buf = fgets ($fp);
    if (preg_match ("/(\d{10} \d{5} [nf])/", $buf)) // Pour chaque ligne valide
    {
    if (!preg_match ("/(0000000000 *)/", $buf)) // N° d'objet valide
    $currObject++;
    }
    }
    $tmp = explode (' ', $buf); // On a l'adresse de l'objet Info
    $offsetInfos = $tmp[0];
    fseek ($fp, $offsetInfos); // On s'y rend !
    fgets ($fp); // Skip object header
    unset ($buf);
    while (! preg_match ('/(>>)/', $buf)) $buf.=fgets ($fp); // on récupère les infos
    $buf = preg_replace ("/(\n)/", "", $buf); // On nettoie les infos
    $retval = preg_replace ("/(>>.*endobj)/", "", $buf);
    $retval = preg_replace ("/(<<)/", "", $retval);
    fclose($fp);
    return ($retval);
    }
    $PdfInfos = getInfos ("essai.pdf");
    $infos = explode ('/', $PdfInfos);
    while (list ($k, $v) = each ($infos))
    {
    $pdfInfos[preg_replace ('/(.*)(\(.*)/', '\\1', $v)] = preg_replace ('/(.*\()(.*)(\).*)/', '\\2', $v);
    }
    print_r ($pdfInfos);


    Voilà.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.