#java #android #zip #compression
#java #Android #zip #сжатие
Вопрос:
В принципе, у меня есть довольно длинный текст, мне нужно сжать его, сохранить в файле и прочитать позже. вот что я сделал.
public static void outCompressNIO(String outFile, String src) {
FileChannel fc = null;
GZIPOutputStream gz = null;
try {
fc = new FileOutputStream(outFile).getChannel();
gz = new GZIPOutputStream(Channels.newOutputStream(fc));
gz.write(src.getBytes());
gz.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
gz.close();
fc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void inCompressNIO(String inFile) {
FileChannel fc = null;
GZIPInputStream gz = null;
try {
fc = new FileInputStream(inFile).getChannel();
gz = new GZIPInputStream(Channels.newInputStream(fc));
byte fileContent[] = new byte[1024];
StringBuilder sb = new StringBuilder();
while ((gz.read(fileContent)) != -1) {
sb.append(new String(fileContent));
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
gz.close();
fc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Но строка, которую я получил обратно из сжатого файла, отличается от исходной от места к месту. Кто-нибудь знает почему? Кстати, моя главная цель состоит в том, что мне нужно эффективно сжать длинную строку (около 15M) в файл и распаковать ее в основную память на Android. Я пытался просто использовать Object IO в Java для достижения этого, это достигается без проблем на моем ПК. Но на Android, если размер объекта string превышает 3 м, требуется вечность, чтобы преобразовать объект, который я получил из ObjectInputStream, в строку. Поэтому я пробую другие способы избежать приведения. Вышеописанное — одна из моих попыток, но поскольку я мало знаю о NIO, я, вероятно, делаю все неправильно, поэтому, если кто-нибудь знает более эффективный способ добиться этого, пожалуйста, укажите мне правильное направление, большое спасибо.
Ответ №1:
- Выбросьте FileChannel и просто используйте FileInputStream. Вы используете java.io здесь действительно нет NIO, за исключением случаев, когда вы получаете канал, так что вы просто делаете это сложным способом.
- Укажите имя кодировки в String.getBytes().
- Сохраните результат чтения (байт[]) в переменной. Используйте эту переменную при добавлении к sb, т.е. sb.append(новая строка (буфер, 0, количество, кодировка));
- Еще лучше, оберните InputStreamReader вокруг GZIPInputStream, созданного с тем же именем кодировки, считайте в массив char[], а не в массив byte[], и используйте sb.append(CharBuffer, 0, count). Это позволяет избежать предположения, которое вы в настоящее время делаете, что прочитанные байты составляют целую строку.