Re: In PL SQL, an uncompress of a too big file raise an error

From: bin ush <binpush3_at_gmail.com>
Date: Tue, 8 Sep 2015 05:14:36 -0700 (PDT)
Message-ID: <c061d257-f2d8-45d7-a1f9-51d4766778ed_at_googlegroups.com>


Le lundi 7 septembre 2015 21:03:50 UTC+2, A. Mehoela a écrit :
> bin ush wrote:
> > Le dimanche 6 septembre 2015 22:12:30 UTC+2, A. Mehoela a écrit :
> >> wrote:
> >>> contenu_decompresse_ RAW (32000);
> >>> contenu_lu_ RAW (32000);
> >>> --
> >>> contenu_decompresse_ := utl_compress.lz_uncompress (contenu_lu_);
> >>>
> >>
> >> Are you really trying to "uncompress" 32000 characters into 32000 characters, or am I missing something?
> >
> > Hello,
> > no, I'm trying to uncompress a file with a size greater than 32000 characters. I want to put the content into a text file that has the necessary size (greater than 32000).
> >
> I'll try once more: look at the lines I copied from your code, once you're awake.
>
> You ARE trying to uncompress 32000 bytes into a variable that can also only hold 32000 bytes.

Oups !!!
Indeed, my eyes were so in code that I was blind ... I have found the solution.
My major problem was the fact that I haven't understood a BLOB could have any quantity of bytes : I thought BLOB was limited to 32767 bytes. After that everything was clearer.
Here is my solution :

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;

Thank you A.Mehoela for your help. Received on Tue Sep 08 2015 - 14:14:36 CEST

Original text of this message