omicronapps / 7-Zip-JBinding-4Android

Android Java wrapper for 7z archiver engine
GNU Lesser General Public License v2.1
122 stars 25 forks source link

Decompressing large files such as 5.9GB, the decompression speed is gradually abnormally slow #27

Open XuXin007 opened 2 years ago

XuXin007 commented 2 years ago

Decompressing large files such as 5.9GB, the decompression speed is gradually abnormally slow

omicronapps commented 2 years ago

The decompression speed of 7-Zip-JBinding-4Android is directly dependent to the implementations of the underlying 7-Zip-JBinding and 7-Zip libraries.

However, you would want to ensure that you are using IInArchive.extract() rather than IInArchive.extractSlow(). Also, you may want to consider extracting in-memory, to the extent possible. As an example, something like the following.

    void extract(File file) {
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
            RandomAccessFileInStream inStream = new RandomAccessFileInStream(randomAccessFile);
            IInArchive inArchive = SevenZip.openInArchive(null, inStream);
            List<MyData> data = new ArrayList<>();
            ArchiveExtractCallback extractCallback = new ArchiveExtractCallback(data);
            inArchive.extract(null, false, extractCallback);
        } catch (SevenZipException e) {
        }
    }

    private class ArchiveExtractCallback implements IArchiveExtractCallback {
        private List<MyData> mData;

        ArchiveExtractCallback(IInArchive inArchive, List<MyData> data) {
            mData = data;
        }

        @Override
        public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
            SequentialOutStream stream = new SequentialOutStream(mData);
            return stream;
        }

        @Override
        public void prepareOperation(ExtractAskMode extractAskMode) throws SevenZipException {
        }

        @Override
        public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {
            if (extractOperationResult != ExtractOperationResult.OK) {
                throw new SevenZipException(extractOperationResult.toString());
            }
        }

        @Override
        public void setTotal(long total) throws SevenZipException {
        }

        @Override
        public void setCompleted(long complete) throws SevenZipException {
        }
    }

    private class SequentialOutStream implements ISequentialOutStream {
        private List<MyData> mData;

        SequentialOutStream(List<MyData> data) {
            mData = data;
        }

        @Override
        public int write(byte[] data) throws SevenZipException {
            if (data == null) {
                throw new SevenZipException("null data");
            }
            mData.add(data);
            return data.length;
        }
    }