1

I looked into at4j and 7-Zip-JBinding (their javadoc and documentation) but they doesn't seem to be able to read without extracting (and get an InputStream from archived file)

Is there any method I'm missing or haven't found ?

a solution other than extracting to a temporary folder to read it

I'm expecting an answer in how to do it in at4j or 7-Zip-JBinding

in other words I want to know how to utilize below mentioned function in at4j or 7-Zip-JBinding

I know java's built in one has getInputStream I'm currently using it this way

import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
 * get input stream of current file
 * @param path path inside zip
 * @return InputStream
 */
public InputStream getInputStream(String path){
    try {
        ZipEntry entry = zipFile.getEntry(path);
        if(entry!=null){
            return zipFile.getInputStream(entry);
        }
        return new ByteArrayInputStream("Not Found".getBytes());
    } catch (Exception ex) {
        //handle exception
    }

    return null;
}

(^^ zipFile is a ZipFile object)

what I want

bhathiya-perera
  • 1,178
  • 12
  • 31

2 Answers2

5

found the solution using 7-Zip-JBinding

just need to use ByteArrayInputStream ,this so far worked for a small file

pass a archive as argument to get all files inside printed

file ExtractItemsSimple.java

import java.io.IOException;
import java.io.RandomAccessFile;
import net.sf.sevenzipjbinding.ISevenZipInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

public class ExtractItemsSimple {
    public static void main(String[] args) {
        RandomAccessFile randomAccessFile = null;
        ISevenZipInArchive inArchive = null;
        try {
            randomAccessFile = new RandomAccessFile(args[0], "r");
            inArchive = SevenZip.openInArchive(null, // autodetect archive type
                    new RandomAccessFileInStream(randomAccessFile));

            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();

            for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[] { 0 };
                if (!item.isFolder()) {
                    System.out.println(ArchieveInputStreamHandler.slurp(new ArchieveInputStreamHandler(item).getInputStream(),1000));
                }
            }
        } catch (Exception e) {
            System.err.println("Error occurs: " + e);
            System.exit(1);
        } finally {
            if (inArchive != null) {
                try {
                    inArchive.close();
                } catch (SevenZipException e) {
                    System.err.println("Error closing archive: " + e);
                }
            }
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    System.err.println("Error closing file: " + e);
                }
            }
        }
    }
}

file ArchieveInputStreamHandler.java

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import net.sf.sevenzipjbinding.ISequentialOutStream;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;



public class ArchieveInputStreamHandler {

    private ISimpleInArchiveItem item;
    private ByteArrayInputStream arrayInputStream;
    public ArchieveInputStreamHandler(ISimpleInArchiveItem item) {
        this.item = item;
    }

    public InputStream getInputStream() throws SevenZipException{

        item.extractSlow(new ISequentialOutStream() {
                        @Override
                        public int write(byte[] data) throws SevenZipException {
                            arrayInputStream = new ByteArrayInputStream(data);
                            return data.length; // Return amount of consumed data
                        }
                    });
        return arrayInputStream;
    }
    //got from http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string
    public static String slurp(final InputStream is, final int bufferSize){
        final char[] buffer = new char[bufferSize];
        final StringBuilder out = new StringBuilder();
        try {
            final Reader in = new InputStreamReader(is, "UTF-8");
            try {
              for (;;) {
                int rsz = in.read(buffer, 0, buffer.length);
                if (rsz < 0)
                  break;
                out.append(buffer, 0, rsz);
              }
            }
            finally {
              in.close();
            }
        }
        catch (UnsupportedEncodingException ex) {
        /* ... */
        }
        catch (IOException ex) {
          /* ... */
        }
        return out.toString();
    }
}
bhathiya-perera
  • 1,178
  • 12
  • 31
  • I'm trying to modify your slurp method to return a InputStream instead. I tried to return this org.apache.commons.io.IOUtils.toInputStream(out.toString(),"UTF-8"); However it doesn't work as expected, when I debug I see that the out string has decode one chunk from the middle of the file. Any ideas of why? – J. Bend Oct 08 '16 at 12:17
  • It write only first amount of data to private ByteArrayInputStream arrayInputStream; You should write to OutPutStream using outStrem.write(data) – Shakirov Ramil Mar 05 '21 at 08:38
0

Are you looking for http://docs.oracle.com/javase/6/docs/api/java/util/zip/ZipInputStream.html which can extract entries in zip file without extracting it completely.