2016-05-13 6 views
3
байт []

Я использую LZ4 для сжатия и распаковки string.I попытались следующим образомдекомпрессию с использованием LZ4

public class CompressionDemo { 

    public static byte[] compressLZ4(LZ4Factory factory, String data) throws IOException { 
     final int decompressedLength = data.getBytes().length; 
     LZ4Compressor compressor = factory.fastCompressor(); 
     int maxCompressedLength = compressor.maxCompressedLength(decompressedLength); 
     byte[] compressed = new byte[maxCompressedLength]; 
     compressor.compress(data.getBytes(), 0, decompressedLength, compressed, 0, maxCompressedLength); 
     return compressed; 

    } 

    public static String deCompressLZ4(LZ4Factory factory, byte[] data) throws IOException { 
     LZ4FastDecompressor decompressor = factory.fastDecompressor(); 
     byte[] restored = new byte[data.length]; 
     decompressor.decompress(data,0,restored, 0,data.length); 
     return new String(restored); 
    } 

    public static void main(String[] args) throws IOException, DataFormatException { 
     String string = "kjshfhshfashfhsakjfhksjafhkjsafhkjashfkjhfjkfhhjdshfhhjdfhdsjkfhdshfdskjfhksjdfhskjdhfkjsdhfk"; 
     LZ4Factory factory = LZ4Factory.fastestInstance(); 
     byte[] arr = compressLZ4(factory, string); 
     System.out.println(arr.length); 
     System.out.println(deCompressLZ4(factory, arr) + "decom"); 
    } 
} 

он дает следующее excpetion

Исключение в потоке «основной» чистый .jpountz.lz4.LZ4Exception: декодирование ошибок смещения 92 входного буфера

проблема здесь состоит в том, что распаковке работает только тогда, когда я передать фактический Строка байт [] длина IE

public static String deCompressLZ4(LZ4Factory factory, byte[] data) throws IOException { 
     LZ4FastDecompressor decompressor = factory.fastDecompressor(); 
     byte[] restored = new byte[data.length]; 
     decompressor.decompress(data,0,restored, 0,"kjshfhshfashfhsakjfhksjafhkjsafhkjashfkjhfjkfhhjdshfhhjdfhdsjkfhdshfdskjfhksjdfhskjdhfkjsdhfk".getBytes().length); 
     return new String(restored); 
    } 

Ожидается фактический размер байт []. Может кто-то помочь мне с этим

+0

@ pppavan- Вы когда-нибудь находили решение своей проблемы? – kit

+0

да я решил это @kit – pppavan

+0

Отлично. @pppavan Можете ли вы дать мне предложение по моей проблеме - https://stackoverflow.com/questions/45398848/how-to-decompress-lzo-byte-array-using-java-lzo-library или, пожалуйста, дайте мне пример для примера декомпрессии массива. – kit

ответ

0

восстановлен байт [] длина слишком мал, вы не должны использовать сжатый data.length, вместо этого вы должны использовать данные []. Длина * 3 или более 3.

+0

Хотя это ответ, вы могли бы предоставить больше информации, чтобы помочь другим? http://stackoverflow.com/help/how-to-answer –

0

I resoved так:

public static byte[] decompress(byte[] finalCompressedArray,String ... extInfo) { 
    int len = finalCompressedArray.length * 3; 
    int i = 5; 
    while (i > 0) { 
     try { 
      return decompress(finalCompressedArray, len); 
     } catch (Exception e) { 
      len = len * 2; 
      i--; 
      if (LOGGER.isInfoEnabled()) { 
       LOGGER.info("decompress Error: extInfo ={} ", extInfo, e); 
      } 

     } 

    } 

    throw new ItemException(1, "decompress error"); 
} 

/** 
* 解压一个数组 
* 
* @param finalCompressedArray 压缩后的数据 
* @param length    原始数据长度, 精确的长度,不能大,也不能小。 
* @return 
*/ 
private static byte[] decompress(byte[] finalCompressedArray, int length) { 
    byte[] desc = new byte[length ]; 
    int decompressLen = decompressor.decompress(finalCompressedArray, desc); 

    byte[] result = new byte[decompressLen]; 
    System.arraycopy(desc,0,result,0,decompressLen); 
    return result; 
} 
0

Я просто столкнулся с теми же ошибками на Android и решил, что на основе выпуска ниже: https://github.com/lz4/lz4-java/issues/68

Короче убедитесь, что вы используете один и тот же завод для обоего операций (compressi на + декомпрессии) и использовать Arrays.copyOf(), как показано ниже:

byte[] compress(final byte[] data) { 
    LZ4Factory lz4Factory = LZ4Factory.safeInstance(); 
    LZ4Compressor fastCompressor = lz4Factory.fastCompressor(); 
    int maxCompressedLength = fastCompressor.maxCompressedLength(data.length); 
    byte[] comp = new byte[maxCompressedLength]; 
    int compressedLength = fastCompressor.compress(data, 0, data.length, comp, 0, maxCompressedLength); 
    return Arrays.copyOf(comp, compressedLength); 
} 

    byte[] decompress(final byte[] compressed) { 
    LZ4Factory lz4Factory = LZ4Factory.safeInstance(); 
    LZ4SafeDecompressor decompressor = lz4Factory.safeDecompressor(); 
    byte[] decomp = new byte[compressed.length * 4];//you might need to allocate more 
    decomp = decompressor.decompress(Arrays.copyOf(compressed, compressed.length), decomp.length); 
    return decomp; 

Надеется, что это поможет.

0

Поскольку сжатие и декомпрессии может происходить на разных машинах или кодировка символов по умолчанию не является одним из форматов Unicode, необходимо также указать кодировку.

В остальном он использует фактические длины сжатия и декомпрессии и лучше сохраняет размер несжатых данных в простом формате, поэтому его можно извлечь до декомпрессии.

public static byte[] compressLZ4(LZ4Factory factory, String data) throws IOException { 
    byte[] decompressed = data.getBytes(StandardCharsets.UTF_8).length; 
    LZ4Compressor compressor = factory.fastCompressor(); 
    int maxCompressedLength = compressor.maxCompressedLength(decompressed.length); 
    byte[] compressed = new byte[4 + maxCompressedLength]; 
    int compressedSize = compressor.compress(decompressed, 0, decompressed.length, 
              compressed, 4, maxCompressedLength); 
    ByteBuffer.wrap(compressed).putInt(decompressed.length); 
    return Arrays.copyOf(compressed, 0, 4 + compressedSize); 
} 

public static String deCompressLZ4(LZ4Factory factory, byte[] data) throws IOException { 
    LZ4FastDecompressor decompressor = factory.fastDecompressor(); 
    int decrompressedLength = ByteBuffer.wrap(data).getInt(); 
    byte[] restored = new byte[decrompressedLength]; 
    decompressor.decompress(data, 4, restored, 0, decrompressedLength); 
    return new String(restored, StandardCharsets.UTF_8); 
} 

Это должно быть сказано, что String не подходит для двоичных данных, и ваше сжатие/декомпрессия только для обработки текста. (String содержит текст Unicode в виде двухбайтовых символов UTF-16. Преобразование в двоичные данные всегда включает в себя преобразование с кодировкой двоичных данных. Это стоит в памяти, скорости и возможном повреждении данных.)

Смежные вопросы