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