Android 解压密码保护Zip文件速度慢,如何使其快速?

Android 解压密码保护Zip文件速度慢,如何使其快速?,android,unzip,fileinputstream,bufferedinputstream,zipoutputstream,Android,Unzip,Fileinputstream,Bufferedinputstream,Zipoutputstream,我使用下面的类来解压受密码保护的文件,但解压速度太慢,无法加快速度,或者对此类或方法进行任何改进。提前谢谢 用于解压密码保护Zip文件的类。 public class ZipDecryptInputStream extends InputStream { private static final int[] CRC_TABLE = new int[256]; private static final int DECRYPT_HEADER_SIZE = 12; privat

我使用下面的类来解压受密码保护的文件,但解压速度太慢,无法加快速度,或者对此类或方法进行任何改进。提前谢谢

用于解压密码保护Zip文件的类。

public class ZipDecryptInputStream extends InputStream {
    private static final int[] CRC_TABLE = new int[256];
    private static final int DECRYPT_HEADER_SIZE = 12;
    private static final int[] LFH_SIGNATURE = {0x50, 0x4b, 0x03, 0x04};

    static {
        for (int i = 0; i < 256; i++) {
            int r = i;
            for (int j = 0; j < 8; j++) {
                if ((r & 1) == 1) {
                    r = (r >>> 1) ^ 0xedb88320;
                } else {
                    r >>>= 1;
                }
            }
            CRC_TABLE[i] = r;
        }
    }

    private final InputStream delegate;
    private final String password;
    private final int[] keys = new int[3];
    private State state = State.SIGNATURE;
    private int skipBytes;
    private int compressedSize;
    private int value;
    private int valuePos;
    private int valueInc;

    public ZipDecryptInputStream(InputStream stream, String password) {
        this.delegate = stream;
        this.password = password;
    }

    @Override
    public int read() throws IOException {
        int result = delegate.read();
        if (skipBytes == 0) {
            switch (state) {
                case SIGNATURE:
                    if (result != LFH_SIGNATURE[valuePos]) {
                        state = State.TAIL;
                    } else {
                        valuePos++;
                        if (valuePos >= LFH_SIGNATURE.length) {
                            skipBytes = 2;
                            state = State.FLAGS;
                        }
                    }
                    break;
                case FLAGS:
                    if ((result & 1) == 0) {
                        throw new IllegalStateException("ZIP not password protected.");
                    }
                    if ((result & 64) == 64) {
                        throw new IllegalStateException("Strong encryption used.");
                    }
                    if ((result & 8) == 8) {
                        throw new IllegalStateException("Unsupported ZIP format.");
                    }
                    result -= 1;
                    compressedSize = 0;
                    valuePos = 0;
                    valueInc = DECRYPT_HEADER_SIZE;
                    state = State.COMPRESSED_SIZE;
                    skipBytes = 11;
                    break;
                case COMPRESSED_SIZE:
                    compressedSize += result << (8 * valuePos);
                    result -= valueInc;
                    if (result < 0) {
                        valueInc = 1;
                        result += 256;
                    } else {
                        valueInc = 0;
                    }
                    valuePos++;
                    if (valuePos > 3) {
                        valuePos = 0;
                        value = 0;
                        state = State.FN_LENGTH;
                        skipBytes = 4;
                    }
                    break;
                case FN_LENGTH:
                case EF_LENGTH:
                    value += result << 8 * valuePos;
                    if (valuePos == 1) {
                        valuePos = 0;
                        if (state == State.FN_LENGTH) {
                            state = State.EF_LENGTH;
                        } else {
                            state = State.HEADER;
                            skipBytes = value;
                        }
                    } else {
                        valuePos = 1;
                    }
                    break;
                case HEADER:
                    initKeys(password);
                    for (int i = 0; i < DECRYPT_HEADER_SIZE; i++) {
                        updateKeys((byte) (result ^ decryptByte()));
                        result = delegate.read();
                    }
                    compressedSize -= DECRYPT_HEADER_SIZE;
                    state = State.DATA;
                    // intentionally no break
                case DATA:
                    result = (result ^ decryptByte()) & 0xff;
                    updateKeys((byte) result);
                    compressedSize--;
                    if (compressedSize == 0) {
                        valuePos = 0;
                        state = State.SIGNATURE;
                    }
                    break;
                case TAIL:
                    // do nothing
            }
        } else {
            skipBytes--;
        }
        return result;
    }

    @Override
    public void close() throws IOException {
        delegate.close();
        super.close();
    }

    private void initKeys(String password) {
        keys[0] = 305419896;
        keys[1] = 591751049;
        keys[2] = 878082192;
        for (int i = 0; i < password.length(); i++) {
            updateKeys((byte) (password.charAt(i) & 0xff));
        }
    }

    private void updateKeys(byte charAt) {
        keys[0] = crc32(keys[0], charAt);
        keys[1] += keys[0] & 0xff;
        keys[1] = keys[1] * 134775813 + 1;
        keys[2] = crc32(keys[2], (byte) (keys[1] >> 24));
    }

    private byte decryptByte() {
        int temp = keys[2] | 2;
        return (byte) ((temp * (temp ^ 1)) >>> 8);
    }

    private int crc32(int oldCrc, byte charAt) {
        return ((oldCrc >>> 8) ^ CRC_TABLE[(oldCrc ^ charAt) & 0xff]);
    }

    private enum State {
        SIGNATURE, FLAGS, COMPRESSED_SIZE, FN_LENGTH, EF_LENGTH, HEADER, DATA, TAIL
    }
}

您是否考虑使用<代码> BytRayOuttoStuts而不是<代码> FielOutPoStuts?前几天我在阅读文件方面也遇到了问题,这花了很多时间,我在谷歌的例子中找到了ByteArrayOutputStream,这对我很有帮助

ByteArrayOutputStream bos=newbytearrayoutputstream();
byte[]ba=新字节[(int)文件[i].length()];
for(int readNum;(readNum=fis.read(ba))!=-1;){
bos.write(ba,0,readNum);
}

同样的结果
InputStream zin = new FileInputStream(new File(zipFilePath)); 
ZipDecryptInputStream inputStream = new ZipDecryptInputStream(zin, "myPassWord");
ZipInputStream zis = new ZipInputStream(inputStream);

ZipEntry ze ;
while ((ze = zis.getNextEntry()) != null) {
    FileOutputStream fos = new FileOutputStream(unzipAtLocation + File.separator + ze.getName());
    int BUFFER = 2048;
    byte[] data = new byte[BUFFER];
    int count;
    while ((count = zis.read(data, 0, BUFFER)) != -1) {
        fos.write(data, 0, count);
    }
}
zis.close();