IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

La décompression d'un fichier trop gros provoque une erreur [11gR2]


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 30
    Par défaut La décompression d'un fichier trop gros provoque une erreur
    Bonjour,

    j'essaie de réaliser un programme permettant la décompression d'un fichier. Pour cela, j'ai employé utl_compress.lz_uncompress
    J'arrive à décompresser les fichiers de petite taille, plus exactement inférieur à la taille d'un BLOB.
    Par contre dès qu'un fichier dépasse cette taille mon programme plante et m'affiche l'erreur ORA-29294 "Une erreur de données est survenue lors de la compression ou de la décompression."

    J'ai essayé de faire la lecture du fichier par tronçon mais je n'y arrive pas
    Voici donc ci dessous le programme qui me prend la tête.

    Merci pour votre aide

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    ===================================================================
       FUNCTION decompression_fichier (interface_           IN VARCHAR2,
                                       nom_fichier_src_     IN VARCHAR2,
                                       nom_fichier_cible_   IN VARCHAR2,
                                       chemin_              IN VARCHAR2)
          RETURN BOOLEAN IS
          pointeur_fic_src_      BFILE;
          contenu_compresse_     BLOB;
          contenu_decompresse_   RAW (32000);      
          pos_depart_src_        INTEGER := 1;
          pos_depart_dst_        INTEGER := 1;
          taille_contenu_        INTEGER;
          taille_restant_        INTEGER;
          taille_a_lire_         INTEGER;
          taille_lecture_        INTEGER := 32000;
          taille_maxlob_         INTEGER := 32000;
          v_file                 UTL_FILE.file_type;
          contenu_lu_            RAW (32000);
          postion_lecture_       INTEGER := 1;
          lecture_               BOOLEAN;
       ----
       BEGIN
          BEGIN
     
             DBMS_LOB.CREATETEMPORARY (contenu_compresse_, TRUE);
             DBMS_LOB.OPEN (contenu_compresse_, DBMS_LOB.LOB_READWRITE);
             pointeur_fic_src_ := BFILENAME (chemin_, nom_fichier_src_);
             DBMS_LOB.fileopen (pointeur_fic_src_, DBMS_LOB.file_readonly);
     
             IF DBMS_LOB.fileexists (pointeur_fic_src_) = 1
             THEN
                DBMS_OUTPUT.put_line (nom_fichier_src_ || ' ouvert');
                v_file := UTL_FILE.fopen (chemin_, nom_fichier_cible_, 'wb');
                taille_restant_ := DBMS_LOB.getlength (pointeur_fic_src_);
     
                DBMS_LOB.loadblobfromfile (contenu_compresse_,                                                                    
                                           pointeur_fic_src_,                                                                      
                                           DBMS_LOB.GETLENGTH (pointeur_fic_src_),                                                
                                           pos_depart_src_,                                                                
                                           pos_depart_dst_);
                lecture_ := TRUE;
     
                WHILE lecture_
                LOOP
                   IF taille_restant_ < taille_maxlob_
                   THEN
                      taille_a_lire_ := taille_restant_;
                      lecture_ := FALSE;
                   ELSE
                      taille_restant_ := taille_restant_ - taille_maxlob_;
                      taille_a_lire_ := taille_maxlob_;
                   END IF;
     
                   DBMS_OUTPUT.put_line ('taille_restant_' || taille_restant_);
                   DBMS_OUTPUT.put_line ('taille_a_lire_' || taille_a_lire_);
                   DBMS_LOB.READ (contenu_compresse_,
                                  taille_a_lire_,
                                  postion_lecture_,
                                  contenu_lu_);
                   postion_lecture_ := postion_lecture_ + taille_a_lire_;
                   DBMS_OUTPUT.put_line ('postion_lecture_' || postion_lecture_);
                   --
                   contenu_decompresse_ := utl_compress.lz_uncompress (contenu_lu_);
     
                   DBMS_OUTPUT.put_line (UTL_RAW.cast_to_varchar2 (contenu_decompresse_));
                   UTL_FILE.put_raw (v_file, contenu_decompresse_);
                   UTL_FILE.fflush (v_file);
                END LOOP;
     
                UTL_FILE.fclose (v_file);
                DBMS_LOB.fileclose (pointeur_fic_src_);
             END IF;
     
     
             DBMS_LOB.FREETEMPORARY (contenu_compresse_);
     
             -----------------
             RETURN TRUE;
          EXCEPTION
             WHEN OTHERS
             THEN
                            IF UTL_FILE.is_open (v_file)
                            THEN
                               UTL_FILE.fclose (v_file);
                            END IF;
                --
                IF (DBMS_LOB.fileisopen (pointeur_fic_src_) = 1)
                THEN
                   DBMS_LOB.fileclose (pointeur_fic_src_);
                END IF;
     
     
                RETURN FALSE;
          END;
       END decompression_fichier;

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Tu ne peux pas décompresser un fichier par bout. Il faut décompresser le fichier complet.
    lz_uncompress peut lire un blob et renvoyer le résultat en BLOB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     function lz_uncompress(src in raw) return raw;
     
      /* This lz_uncompress overload will return a temporary BLOB for the uncompressed data.  */
      function lz_uncompress(src in blob) return blob;
     
      /* This lz_uncompress overload will return the uncompressed data into the existing BLOB, dst.  Original dst data will be overwritten.  */
      procedure lz_uncompress(src in blob, dst in out nocopy blob);
     
     
      /* This lz_uncompress overload will return a temporary BLOB for the uncompressed data.   */
      function lz_uncompress(src in bfile) return blob;
     
      /* This lz_uncompress overload will return the uncompressed data into the existing BLOB, dst.  Original dst data will be overwritten.   */
      procedure lz_uncompress(src in bfile, dst in out nocopy blob);

  3. #3
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 30
    Par défaut ça marche !
    Bonjour,
    merci MCM, tu m'as mis sur la voie et j'ai fini par comprendre (tout du moins, je crois...) ce qui n'allait pas dans mon programme.
    Je n'avais pas vu qu'un BLOB avait une taille 'quelconque', et surtout pas limitée à 32767 octets
    Sachant alors que tout mon fichier compressé tenait dans un BLOB, il n'y avait plus qu'à lire ce BLOB pour le mettre dans un fichier, via le type RAW (qui est limité à 32767 octets).

    Merci !

    voici le code corrigé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
      FUNCTION decompression_fichier (nom_fichier_src_     IN VARCHAR2,
                                       nom_fichier_cible_   IN VARCHAR2,
                                       chemin_              IN VARCHAR2)
          RETURN BOOLEAN IS
          pointeur_fic_src_      BFILE := NULL;
          contenu_compresse_     BLOB;
          contenu_decompresse_   BLOB;
          pos_depart_src_        INTEGER := 1;
          pos_depart_dst_        INTEGER := 1;
          taille_blob_           INTEGER;
          fic_cible_             UTL_FILE.file_type;
          contenu_lu_            RAW (32767);
          debut_lecture_         NUMBER := 1;
          taille_a_lire_         BINARY_INTEGER := 32767;
       ----
       BEGIN
          BEGIN
     
             DBMS_LOB.createtemporary (contenu_compresse_, TRUE);
             -- Initialise le pointeur correspondant au fichier source compressé
             pointeur_fic_src_ := BFILENAME (chemin_, nom_fichier_src_);
     
             IF DBMS_LOB.fileexists (pointeur_fic_src_) = 1
             THEN
                DBMS_LOB.fileopen (pointeur_fic_src_, DBMS_LOB.file_readonly);
                -- Copie de tout le fichier compressé dans un BLOB
                DBMS_LOB.loadblobfromfile (contenu_compresse_,
                                           pointeur_fic_src_,
                                           DBMS_LOB.lobmaxsize,
                                           pos_depart_src_,
                                           pos_depart_dst_);
                -- Le BLOB ayant le contenu compressé est décompressé dans un BLOB
                contenu_decompresse_ := utl_compress.lz_uncompress (contenu_compresse_);
                fic_cible_ :=
                   UTL_FILE.fopen (chemin_,
                                   nom_fichier_cible_,
                                   'wb',
                                   32767);
                taille_blob_ := DBMS_LOB.getlength (contenu_decompresse_);
     
                -- Si la taille de la décompression passe en une seule écriture
                IF taille_blob_ < 32767
                THEN
                   UTL_FILE.put_raw (fic_cible_, contenu_decompresse_, TRUE);
                --               UTL_FILE.fflush (fic_cible_);
                ELSE
                   -- Parcours morceau par morceau de la décompression
                   --   la taille de chaque morceau correspond à la taille maxi d'un RAW
                   WHILE debut_lecture_ < taille_blob_
                   LOOP
                      --
                      IF debut_lecture_ + taille_a_lire_ > taille_blob_
                      THEN
                         taille_a_lire_ := (taille_blob_ + 1) - debut_lecture_;
                      END IF;
     
                      DBMS_LOB.read (contenu_decompresse_,
                                     taille_a_lire_,
                                     debut_lecture_,
                                     contenu_lu_);
                      UTL_FILE.put_raw (fic_cible_, contenu_lu_, TRUE);
                      debut_lecture_ := debut_lecture_ + taille_a_lire_;
                   --
                   END LOOP;
                END IF;
     
                UTL_FILE.fclose (fic_cible_);
                DBMS_LOB.FILECLOSE (pointeur_fic_src_);
             END IF;
     
             DBMS_LOB.FREETEMPORARY (contenu_compresse_);
             RETURN TRUE;
          EXCEPTION
             WHEN OTHERS
             THEN
                IF UTL_FILE.is_open (fic_cible_)
                THEN
                   UTL_FILE.fclose (fic_cible_);
                END IF;
     
                --
                IF (DBMS_LOB.fileisopen (pointeur_fic_src_) = 1)
                THEN
                   DBMS_LOB.fileclose (pointeur_fic_src_);
                END IF;
     
                --  ...
     
                RETURN FALSE;
          END;
       END decompression_fichier;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PHP 5.0] Prévenir utilisateur que fichier trop gros
    Par afrodje dans le forum Langage
    Réponses: 2
    Dernier message: 05/03/2009, 09h08
  2. formulaire non soumis si fichier trop gros
    Par atom41 dans le forum Langage
    Réponses: 3
    Dernier message: 30/10/2008, 16h57
  3. Réponses: 2
    Dernier message: 21/03/2008, 15h57
  4. [Upload] fichier trop gros : serveur introuvable
    Par Patrick dans le forum Langage
    Réponses: 1
    Dernier message: 16/10/2007, 14h05
  5. Fichier trop gros = réinitialisation
    Par Artusamak dans le forum Langage
    Réponses: 11
    Dernier message: 19/12/2006, 22h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo