Extract zip file inline in Oracle OCI - Object Storage without downloading to save time

Viewed 63

Is it possible to extract a zip file 'inline' which is in cloud say Oracle cloud, Object storage. Meaning, without downloading it and extracting it in the o/s and re-uploading it to object storage, because the file size is big and we need to save time on upload/download.. Any sample code, with Oracle Functions, or python, java etc. ? Is it possible ? I tried with S3 browser/explorer or other similar tools, but that basically at the background, downloads and extract on local computer.

1 Answers

If I understand the question correctly, your use case would be that you have a compressed value on the server and want to extract it on the server and keep it there.

This is possible and mostly depends on how the values has been compressed. If you use the Lempel-Ziv-Welch algorithm used in the UTL_COMPRESS package, you can extract it directly in PL/SQL.

For other formats like zip, you will need to use some custom Java code like the following example:

CREATE OR REPLACE
JAVA SOURCE NAMED ZIP_Java
AS
import java.io.*;
import java.util.zip.ZipEntry;  
import java.util.zip.ZipOutputStream;  
import java.util.zip.ZipInputStream;  

import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.BufferedOutputStream; 

import java.sql.Blob;  
  
public class Java_Class {  
    public static int ZipBlob(Blob inLob, Blob[] outLob, String filename) {  
        try {  
            // create the zipoutputstream from the end of the outLob  
            Blob            zipLob = outLob[0];
            OutputStream    os     = zipLob.setBinaryStream(1);
            ZipOutputStream zos    = new ZipOutputStream(os);
  
            // add one zip entry
            ZipEntry entry = new ZipEntry(filename);
            zos.putNextEntry(entry);
  
            // write data to the zip lob
            long len = inLob.length();
            long offset = 0;
            byte[] buffer;
            int chunksize = 32768;
            while (offset < len) {
                buffer = inLob.getBytes(offset + 1, chunksize);
                if (buffer == null)
                    break;
                zos.write(buffer, 0, buffer.length);
                offset += buffer.length;
            }
        zos.closeEntry();
        zos.close();
        outLob[0] = zipLob;
  
        } catch (Exception e) {  
            System.out.println("Exception: " + e.toString());
            e.printStackTrace(System.out);  
            return 0;  
        }  
         
    return 1;  
    }  

    public static int UnzipBlob(Blob inLob, Blob[] outLob, String filename) {  
        try {  
            final int       kBUFFER = 2048;
         
            InputStream     inps    = inLob.getBinaryStream();
            ZipInputStream  zis     = new ZipInputStream(inps);
            ZipEntry        entry;
      
            Blob            fileLob = outLob[0];
            OutputStream    os      = fileLob.setBinaryStream(1);
 
            while((entry = zis.getNextEntry()) != null) {
                if (entry.getName().equalsIgnoreCase(filename)) {
                    byte data[] = new byte[kBUFFER];
 
                    BufferedOutputStream dest = new BufferedOutputStream(os, kBUFFER);
                    int count;
                    while ((count = zis.read(data, 0, kBUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                    dest.close();
                }
            }
            zis.close();
            return 1;
        } catch (Exception e) {
            System.out.println("Exception: " + e.toString());
            e.printStackTrace();
            return 0;
        }
    }
}  
/  

CREATE OR REPLACE
FUNCTION ZipBlobJava(theSource IN BLOB, theDestination IN OUT NOCOPY BLOB, theFilename IN VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA NAME 'Java_Class.ZipBlob(java.sql.Blob, java.sql.Blob[], java.lang.String) return int';
/

CREATE OR REPLACE
FUNCTION UnzipBlobJava(theSource IN BLOB, theDestination IN OUT NOCOPY BLOB, theFilename IN VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA NAME 'Java_Class.UnzipBlob(java.sql.Blob, java.sql.Blob[], java.lang.String) return int';
/
Related