Re: In PL SQL, an uncompress of a too big file raise an error
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
