323 lines
10 KiB
Plaintext
323 lines
10 KiB
Plaintext
|
package com.novelbook.android.utils;
|
|||
|
|
|||
|
import java.io.ByteArrayInputStream;
|
|||
|
import java.io.ByteArrayOutputStream;
|
|||
|
import java.io.File;
|
|||
|
import java.io.FileInputStream;
|
|||
|
import java.io.FileOutputStream;
|
|||
|
import java.io.IOException;
|
|||
|
import java.io.InputStream;
|
|||
|
import java.io.OutputStream;
|
|||
|
import java.util.Enumeration;
|
|||
|
import java.util.zip.GZIPInputStream;
|
|||
|
import java.util.zip.GZIPOutputStream;
|
|||
|
import java.util.zip.ZipEntry;
|
|||
|
import java.util.zip.ZipFile;
|
|||
|
import java.util.zip.ZipOutputStream;
|
|||
|
|
|||
|
/**
|
|||
|
* Created by 眼神 on 2018/3/27.
|
|||
|
* 类描述:处理压缩数据的工具
|
|||
|
*/
|
|||
|
public class CompressUtils {
|
|||
|
private static final int BUFFER_LENGTH = 400;
|
|||
|
|
|||
|
//压缩字节最小长度,小于这个长度的字节数组不适合压缩,压缩完会更大
|
|||
|
public static final int BYTE_MIN_LENGTH = 50;
|
|||
|
|
|||
|
//字节数组是否压缩标志位
|
|||
|
public static final byte FLAG_GBK_STRING_UNCOMPRESSED_BYTEARRAY = 0;
|
|||
|
public static final byte FLAG_GBK_STRING_COMPRESSED_BYTEARRAY = 1;
|
|||
|
public static final byte FLAG_UTF8_STRING_COMPRESSED_BYTEARRAY = 2;
|
|||
|
public static final byte FLAG_NO_UPDATE_INFO = 3;
|
|||
|
|
|||
|
/**
|
|||
|
* 数据压缩
|
|||
|
*
|
|||
|
* @param is
|
|||
|
* @param os
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public static void compress(InputStream is, OutputStream os) throws Exception {
|
|||
|
GZIPOutputStream gos = new GZIPOutputStream(os);
|
|||
|
int count;
|
|||
|
byte data[] = new byte[BUFFER_LENGTH];
|
|||
|
while ((count = is.read(data, 0, BUFFER_LENGTH)) != -1) {
|
|||
|
gos.write(data, 0, count);
|
|||
|
}
|
|||
|
gos.finish();
|
|||
|
|
|||
|
gos.flush();
|
|||
|
gos.close();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 数据解压缩
|
|||
|
*
|
|||
|
* @param is
|
|||
|
* @param os
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public static void decompress(InputStream is, OutputStream os) throws Exception {
|
|||
|
|
|||
|
GZIPInputStream gis = new GZIPInputStream(is);
|
|||
|
|
|||
|
int count;
|
|||
|
byte data[] = new byte[BUFFER_LENGTH];
|
|||
|
while ((count = gis.read(data, 0, BUFFER_LENGTH)) != -1) {
|
|||
|
os.write(data, 0, count);
|
|||
|
}
|
|||
|
|
|||
|
gis.close();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 数据解压缩
|
|||
|
*
|
|||
|
* @param is
|
|||
|
* @throws Exception return 返回解析好的json字符串
|
|||
|
*/
|
|||
|
public static String decompress(InputStream is) throws Exception {
|
|||
|
|
|||
|
GZIPInputStream gis = new GZIPInputStream(is);
|
|||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|||
|
int count;
|
|||
|
byte data[] = new byte[BUFFER_LENGTH];
|
|||
|
while ((count = gis.read(data, 0, BUFFER_LENGTH)) != -1) {
|
|||
|
os.write(data, 0, count);
|
|||
|
}
|
|||
|
os.close();
|
|||
|
gis.close();
|
|||
|
return new String(os.toByteArray());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 数据压缩
|
|||
|
*
|
|||
|
* @param data
|
|||
|
* @return
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public static byte[] byteCompress(byte[] data) throws Exception {
|
|||
|
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
|||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|||
|
|
|||
|
// 压缩
|
|||
|
compress(bais, baos);
|
|||
|
|
|||
|
byte[] output = baos.toByteArray();
|
|||
|
|
|||
|
baos.flush();
|
|||
|
baos.close();
|
|||
|
|
|||
|
bais.close();
|
|||
|
|
|||
|
return output;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 数据解压缩
|
|||
|
*
|
|||
|
* @param data
|
|||
|
* @return
|
|||
|
* @throws Exception
|
|||
|
*/
|
|||
|
public static byte[] byteDecompress(byte[] data) throws Exception {
|
|||
|
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
|||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|||
|
|
|||
|
// 解压缩
|
|||
|
|
|||
|
decompress(bais, baos);
|
|||
|
|
|||
|
data = baos.toByteArray();
|
|||
|
|
|||
|
baos.flush();
|
|||
|
baos.close();
|
|||
|
|
|||
|
bais.close();
|
|||
|
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 压缩文件
|
|||
|
*
|
|||
|
* @param src
|
|||
|
* @param dest
|
|||
|
* @throws IOException
|
|||
|
*/
|
|||
|
public static void zip(String src, String dest) throws IOException {
|
|||
|
//提供了一个数据项压缩成一个ZIP归档输出流
|
|||
|
ZipOutputStream out = null;
|
|||
|
try {
|
|||
|
|
|||
|
File outFile = new File(dest);//源文件或者目录
|
|||
|
File fileOrDirectory = new File(src);//压缩文件路径
|
|||
|
out = new ZipOutputStream(new FileOutputStream(outFile));
|
|||
|
//如果此文件是一个文件,否则为false。
|
|||
|
if (fileOrDirectory.isFile()) {
|
|||
|
zipFileOrDirectory(out, fileOrDirectory, "");
|
|||
|
} else {
|
|||
|
//返回一个文件或空阵列。
|
|||
|
File[] entries = fileOrDirectory.listFiles();
|
|||
|
for (int i = 0; i < entries.length; i++) {
|
|||
|
// 递归压缩,更新curPaths
|
|||
|
zipFileOrDirectory(out, entries[i], "");
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
} finally {
|
|||
|
//关闭输出流
|
|||
|
if (out != null) {
|
|||
|
try {
|
|||
|
out.close();
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 压缩文件
|
|||
|
*
|
|||
|
* @param out
|
|||
|
* @param fileOrDirectory
|
|||
|
* @param curPath
|
|||
|
* @throws IOException
|
|||
|
*/
|
|||
|
private static void zipFileOrDirectory(ZipOutputStream out,
|
|||
|
File fileOrDirectory, String curPath) throws IOException {
|
|||
|
//从文件中读取字节的输入流
|
|||
|
FileInputStream in = null;
|
|||
|
try {
|
|||
|
//如果此文件是一个目录,否则返回false。
|
|||
|
if (!fileOrDirectory.isDirectory()) {
|
|||
|
// 压缩文件
|
|||
|
byte[] buffer = new byte[4096];
|
|||
|
int bytes_read;
|
|||
|
in = new FileInputStream(fileOrDirectory);
|
|||
|
//实例代表一个条目内的ZIP归档
|
|||
|
ZipEntry entry = new ZipEntry(curPath
|
|||
|
+ fileOrDirectory.getName());
|
|||
|
//条目的信息写入底层流
|
|||
|
out.putNextEntry(entry);
|
|||
|
while ((bytes_read = in.read(buffer)) != -1) {
|
|||
|
out.write(buffer, 0, bytes_read);
|
|||
|
}
|
|||
|
out.closeEntry();
|
|||
|
} else {
|
|||
|
// 压缩目录
|
|||
|
File[] entries = fileOrDirectory.listFiles();
|
|||
|
for (int i = 0; i < entries.length; i++) {
|
|||
|
// 递归压缩,更新curPaths
|
|||
|
zipFileOrDirectory(out, entries[i], curPath
|
|||
|
+ fileOrDirectory.getName() + "/");
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
// throw ex;
|
|||
|
} finally {
|
|||
|
if (in != null) {
|
|||
|
try {
|
|||
|
in.close();
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 解压
|
|||
|
*
|
|||
|
* @param zipFileName 压缩文件的文件名
|
|||
|
* @param outputDirectory 解压后的路径
|
|||
|
* @throws IOException
|
|||
|
*/
|
|||
|
@SuppressWarnings("unchecked")
|
|||
|
public static void unzip(String zipFileName, String outputDirectory)
|
|||
|
throws IOException {
|
|||
|
ZipFile zipFile = null;
|
|||
|
try {
|
|||
|
zipFile = new ZipFile(zipFileName);
|
|||
|
Enumeration e = zipFile.entries();
|
|||
|
ZipEntry zipEntry = null;
|
|||
|
File dest = new File(outputDirectory);
|
|||
|
dest.mkdirs();
|
|||
|
while (e.hasMoreElements()) {
|
|||
|
zipEntry = (ZipEntry) e.nextElement();
|
|||
|
String entryName = zipEntry.getName();
|
|||
|
InputStream in = null;
|
|||
|
FileOutputStream out = null;
|
|||
|
try {
|
|||
|
if (zipEntry.isDirectory()) {
|
|||
|
String name = zipEntry.getName();
|
|||
|
name = name.substring(0, name.length() - 1);
|
|||
|
File f = new File(outputDirectory + File.separator
|
|||
|
+ name);
|
|||
|
f.mkdirs();
|
|||
|
} else {
|
|||
|
int index = entryName.lastIndexOf("\\");
|
|||
|
if (index != -1) {
|
|||
|
File df = new File(outputDirectory + File.separator
|
|||
|
+ entryName.substring(0, index));
|
|||
|
df.mkdirs();
|
|||
|
}
|
|||
|
index = entryName.lastIndexOf("/");
|
|||
|
if (index != -1) {
|
|||
|
File df = new File(outputDirectory + File.separator
|
|||
|
+ entryName.substring(0, index));
|
|||
|
df.mkdirs();
|
|||
|
}
|
|||
|
File f = new File(outputDirectory + File.separator
|
|||
|
+ zipEntry.getName());
|
|||
|
// f.createNewFile();
|
|||
|
in = zipFile.getInputStream(zipEntry);
|
|||
|
out = new FileOutputStream(f);
|
|||
|
int c;
|
|||
|
byte[] by = new byte[1024];
|
|||
|
while ((c = in.read(by)) != -1) {
|
|||
|
out.write(by, 0, c);
|
|||
|
}
|
|||
|
out.flush();
|
|||
|
}
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
throw new IOException("解压失败:" + ex.toString());
|
|||
|
} finally {
|
|||
|
if (in != null) {
|
|||
|
try {
|
|||
|
in.close();
|
|||
|
} catch (IOException ex) {
|
|||
|
}
|
|||
|
}
|
|||
|
if (out != null) {
|
|||
|
try {
|
|||
|
out.close();
|
|||
|
} catch (IOException ex) {
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (IOException ex) {
|
|||
|
ex.printStackTrace();
|
|||
|
throw new IOException("解压失败:" + ex.toString());
|
|||
|
} finally {
|
|||
|
if (zipFile != null) {
|
|||
|
try {
|
|||
|
zipFile.close();
|
|||
|
} catch (IOException ex) {
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|