Util.zip. Поврежденные данные, выкачивающие данные в Java, раздувающие в Android - PullRequest
0 голосов
/ 28 октября 2019

У меня проблема с библиотекой java.util.zip, мое требование - сжать некоторые данные на сервере, распаковать и прочитать их на устройстве Android. Я получил некоторые поврежденные данные, поэтому я попробовал упрощенный тест с ПК, и я мог видеть в отладчике, где он вышел из строя, но я не могу понять, почему. Согласно документации, Java VM и Android используют один и тот же алгоритм сжатия, но байты в том виде, в котором они были записаны дефлятором Java, не были должным образом восстановлены инфлятором в Android. Java VM:

~> java -version
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-suse-lp150.7.1-x8664)
OpenJDK 64-Bit Server VM (build 10.0.2+13-suse-lp150.7.1-x8664, mixed mode)

Среда Android эмулятор: Nexus 5X API 29 x86 (процессор x86)]. В комментарии в коде я добавлю некоторые детали. Deflate на JVM:

byte[] pArray = //Input data
//Before compression, size = 20 bytes
//Data: [-67, 77, 12, 20, -65, 85, -106, 39, -64, 34, 88, -68, 63, -56, -114, -39, -65, 76, 28, -81]
try {
    Deflater def = new Deflater();
    def.setInput(pArray);
    def.finish();

    int compressedDataLength = def.deflate(pArray);
    def.end();
    //After compression data size is still 20 bytes 
    //Data: [120, -100, -85, -104, -61, 35, -78, 63, 116, -102, -6, 1, -91, -120, 61, -10, 39, -6, 110, -18]

    FileOutputStream fout = new FileOutputStream(filePath);
    fout.write(pArray, 0, compressedDataLength);

    fout.flush();
    fout.close();           
} catch (IOException e) {
    log.error("IO Exception writing compressed data. {}", e);           
}

Inflate на Android:

private byte[] expandCompressedData(byte[] cData, int expectedSize) {
    //Data coming from the files, 20 bytes equal to those written on the PC
    //Data: [120, -100, -85, -104, -61, 35, -78, 63, 116, -102, -6, 1, -91, -120, 61, -10, 39, -6, 110, -18]
    //expectedSize = 20
    byte expData[] = null;
    try {
        Inflater decompresser = new Inflater();
        decompresser.setInput(cData, 0, cData.length);

        expData = new byte[expectedSize];
        int resultLength = decompresser.inflate(expData);
        //First issue here resultLength = 16
        if (resultLength <= 0) {
            throw new DataExtractionException("Something went wrong extracting file data. Extracted data size: {}" + resultLength);
        }
        decompresser.end();
    } catch (java.util.zip.DataFormatException ex) {
        throw new DataExtractionException("DataFormatException extracting file data: {}" + ex);
    }
    //The data returned is the same as the input, but truncated and padded by zeroes
    //Data: [120, -100, -85, -104, -61, 35, -78, 63, 116, -102, -6, 1, -91, -120, 61, -10, 0, 0, 0, 0 ]
    return expData;
}

Кто-нибудь имеет представление о том, почему дефлятор не любит и не извлекает эти данные?

_______________________________

Обновление:

После дальнейшего тестирования я понял, что проблема не имеет ничего общего с JVM -> Android. Я не знаю почему, но эта конкретная последовательность байтов не может быть сжата и восстановлена. Для ясности могу добавить, что байты поступают из массива с плавающей точкой, но это не имеет значения, ошибка происходит независимо от преобразования. Может ли это быть ошибкой в ​​реализации BZIP? В моем случае я решил эту проблему, используя формат gzip.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...