Re: Zipping multiple BLOBs
cdef wrote:
After doing some tweaking and a lot of face-palming, I have reworked
my EXACT code and ended up with EXACTLY this:
CREATE OR REPLACE TYPE res_blob_zip AS TABLE OF BLOB
/
CREATE OR REPLACE TYPE RES_FILE_NAME_NT AS TABLE OF VARCHAR2(2000)
/
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "ZIPImpl" AS
import java.io.*;
import java.util.zip.*;
import java.sql.Blob;
import oracle.sql.ARRAY;
public class ZIPImpl
{
public static void zipBlob(oracle.sql.ARRAY blobList,
oracle.sql.ARRAY nameList, java.sql.Blob[] outBlob) throws Exception
{
Blob[] blobs = (Blob[]) blobList.getArray();
String[] names = (String[]) nameList.getArray();
int blobCount = blobs.length;
int nameCount = names.length;
Blob zipLob = outBlob[0];
Apparently 'outBlob[0]' is 'null'.
When you create a reference (non-primitive) array of a certain length, say
'n', all n entries are 'null' unless set to a different value explicitly.
OutputStream os = zipLob.setBinaryStream(0);
zipLob = null;
ZipOutputStream zos = new ZipOutputStream(os);
int chunkSize = 32768;
//Now from this source Blob file, we need to get a stream and
then write that stream into Zipped Output
for (int i = 0; i<= (blobCount - 1); i++)
{
Blob src = blobs[i];
//Create a zip entry for the filename
ZipEntry entry = new ZipEntry(names[i]);
zos.putNextEntry(entry);
long len = src.length();
long offset = 1;
byte[] buffer;
while (offset < len)
{
buffer = src.getBytes(offset, chunkSize);
if (buffer == null)
break;
zos.write(buffer,0,buffer.length);
offset += buffer.length;
}
zos.closeEntry();
}
zos.close();
outBlob[0] = zipLob;
}
}
/
ALTER JAVA CLASS "ZIPImpl" RESOLVE
/
CREATE OR REPLACE PACKAGE res_zip
IS
PROCEDURE zipBlob(blob_list IN res_blob_zip,
name_list IN res_file_name_nt,
blob_zip OUT BLOB);
END res_zip;
/
CREATE OR REPLACE PACKAGE BODY res_zip
IS
PROCEDURE zipBlob(blob_list IN res_blob_zip,
name_list IN res_file_name_nt,
blob_zip OUT BLOB)
AS LANGUAGE JAVA
NAME
'ZIPImpl.zipBlob(oracle.sql.ARRAY,oracle.sql.ARRAY,java.sql.Blob[])';
END res_zip;
/
I have reworked my PL/SQL code to call the procedure zipBlob exactly
ONE time after filling the blob and filename tables to pass in as
arrays
res_zip.zipBlob(blob_list,name_list,blob_zip);
My issue now is that I am receiving the following error caused by the
declaration of "OutputStream os = zipLob.setBinaryStream(0);" in the
Java code:
Java call terminated by uncaught Java exception:
java.lang.NullPointerException
From the error message one can see that 'zipLob' is 'null'. If you
dereference a 'null' pointer (a.k.a. reference) you get that exception.
I have tried "OutputStream os = zipLob.setBinaryStream(1);" as well as
You still have to set 'zipLob' to a non-'null' value first.
declaring zipBlob [sic] as "Blob zipLob = blobs[0];", and "Blob zipLob =
null;" but I still receive the error.
Sure, because both those assignments must be (and the second one explicitly
is) assigning 'null' to 'zipLob'. In order to dereference a pointer
successfully it must be non-'null'.
--
Lew