Распаковка строк в строки с помощью Snappy в Java

Я пытаюсь сжать Strings, записывая их в файлы (как Strings) и распаковывая эти файлы. Для сжатия я написал эту функцию:

public static String compress(String s) throws IOException {
    byte[] by = Snappy.compress(s, StandardCharsets.UTF_8);
    return new String(by, StandardCharsets.UTF_8);
}

а затем, для распаковки,

public static String uncompress(String s) throws IOException {
    byte[] by = s.getBytes(StandardCharsets.UTF_8);
    return Snappy.uncompressString(by, StandardCharsets.UTF_8);
}

Но я получаю FAILED_TO_UNCOMPRESS(5), и, глядя на данные, Snappy.compress(s, StandardCharsets.UTF_8) не дает того же результата, что и применение getBytes(StandardCharsets.UTF_8) к данным, сжатым с помощью моей функции compress. Ты знаешь почему? И как я мог сжимать и распаковывать в Strings? Спасибо!


person Matei Oltean    schedule 28.06.2017    source источник
comment
Почему вы сохраняете результат в объекте String в методе compress? Строки не подходят для хранения произвольных байтов. Сделайте так, чтобы метод compress возвращал byte[] вместо String, а метод uncompress принимал в качестве аргумента byte[] вместо String. Если вам действительно нужно хранить байты в строке, вам придется использовать что-то вроде кодировки base 64.   -  person Jesper    schedule 28.06.2017


Ответы (2)


Сжатие приводит к байтам, и вам нужно хранить их как байты, пока вы снова не распаковаете их. Вы не можете преобразовать сжатые байты обратно в String (byte[] может даже не содержать действительного UTF-8).

Теперь вы спросите «а как мне сохранить сжатый String в файл?». Ну, вы собираетесь сохранить его в бинарный файл, то есть писать байты вместо строк. Это означает, что вы не можете редактировать файл в блокноте или даже просматривать файл (ну, вы можете, но это будет искаженный беспорядок).

person Kayaman    schedule 28.06.2017

Это работает, используйте Base64.getEncoder() и Base64.getDecoder()

BitShuffle.unshuffleIntArray(Snappy.uncompress(Base64.getDecoder().decode(new String(Base64.getEncoder().encode(Snappy.compress(BitShuffle.shuffle(new int[]{1, 2, 3})))))));

Хотя snappy использует меньше места в байтах, чем строка Base64. Кроме того, кодирование/декодирование добавляет ~ 45% производительности, необязательные накладные расходы, которые snappy пытается уменьшить.

person norbertas.gaulia    schedule 01.11.2020