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) {
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|