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