Java中实现zip的压缩与解压缩
1 基本概念
ZipOutputStream 实现文件的压缩
ZipOutputStream (OutputStream out) 创建新的zip输出流
void putNextEntry(ZipEntry e) 开始写入新的zip文件条目并将流定位到条目数据的开始处
条目指的是一个文件夹下的多个文件。
ZipEntry(String name) 使用指定名称创建新的zip条目
ZipIutputStream实现文件的解压
ZipIutputStream (IutputStream out) 创建新的zip输入流
ZipEntry getNextEntry()读取下一个zip条目并将流定位到该条目数据的开始处
2 zip压缩
2.1 zip压缩代码实现
程序完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Uzip { /** * 压缩 */ public static void zip(String input, String output, String name) throws Exception { //要生成的压缩文件 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(output)); String[] paths = input.split("\\|"); File[] files = new File[paths.length]; byte[] buffer = new byte[1024]; for (int i = 0; i < paths.length; i++) { files[i] = new File(paths[i]); } for (int i = 0; i < files.length; i++) { FileInputStream fis = new FileInputStream(files[i]); if (files.length == 1 && name != null) { out.putNextEntry(new ZipEntry(name)); } else { out.putNextEntry(new ZipEntry(files[i].getName())); } int len; // 读入需要下载的文件的内容,打包到zip文件 while ((len = fis.read(buffer)) > 0) { out.write(buffer, 0, len); } out.closeEntry(); fis.close(); } out.close(); } public static void main(String[ ] args){ try { zip("E:\\Testzip\\test\\ytt.html","E:\\Test.zip","testytt"); } catch (Exception e) { e.printStackTrace(); } } } |
maven依赖:
1 2 3 4 5 |
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.12</version> </dependency> |
运行程序:
3.程序解读:
ZipEntry(String name) 只能实现一个固定条目的压缩,也就是你压缩什么就得写仔细它的路径,多个子文件压缩写法如下:
1 2 3 4 5 6 7 8 |
public static void main(String[ ] args){ try { zip("E:\\Testzip\\test\\ytt.html|E:\\Testzip\\uugg.html","E:\\Test.zip",null); } catch (Exception e) { e.printStackTrace(); } } } |
注意:
一定要写全E:\\Testzip\\test\\ytt.html,如果写E:\\Testzip\\test\\ytt会报错,报错信息无访问权限。
String input :定义的是待压缩文件的条目。
String output:定义得到的压缩文件包.zip的名字。
String name:定义压缩后的条目的名字,如果与压缩前保持一致,定义name为null即可。
此程序无法实现对空文件夹的压缩。
2.2 zip压缩代码改进
改进的代码可以实现对任意文件的压缩,注意要写全文件类型,比如ytt.html,不允许省略.html。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * date: 2019/07/26 * writed by yangtingting */ public class FileZip { /** * zip文件压缩 * @param inputFile 待压缩文件夹/文件名 * @param outputFile 生成的压缩包名字 */ public static void ZipCompress(String inputFile, String outputFile) throws Exception { //创建zip输出流 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile)); //创建缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(out); File input = new File(inputFile); compress(out, bos, input,null); bos.close(); out.close(); } /** * @param name 压缩文件名,可以写为null保持默认 */ //递归压缩 public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException { if (name == null) { name = input.getName(); } //如果路径为目录(文件夹) if (input.isDirectory()) { //取出文件夹中的文件(或子文件夹) File[] flist = input.listFiles(); if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入 { out.putNextEntry(new ZipEntry(name + "/")); } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩 { for (int i = 0; i < flist.length; i++) { compress(out, bos, flist[i], name + "/" + flist[i].getName()); } } } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中 { out.putNextEntry(new ZipEntry(name)); FileInputStream fos = new FileInputStream(input); BufferedInputStream bis = new BufferedInputStream(fos); int len; //将源文件写入到zip文件中 byte[] buf = new byte[1024]; while ((len = bis.read(buf)) != -1) { bos.write(buf,0,len); } bis.close(); fos.close(); } } public static void main(String[] args) { try { ZipCompress("D:\\Test", "D:\\TestbyYTT.zip"); } catch (Exception e) { e.printStackTrace(); } } } |
3 zip解压
3.1 zip不完美实现
这个网上有很多代码的,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package file; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; public class Decompressing { public static void main(String[] args) { File file = new File("E:\\hello.zip");//当前压缩文件 ZipInputStream zin;//创建ZipInputStream对象 try { ZipFile zipFile = new ZipFile(file);//创建压缩文件对象 zin = new ZipInputStream(new FileInputStream(file));//实例化对象,指明要解压的文件 ZipEntry entry ; while (((entry=zin.getNextEntry())!=null)&& !entry.isDirectory()){//如果entry不为空,并不在同一个目录下 File tmp = new File(entry.getName());//解压出的文件路径 if (!tmp.exists()){//如果文件不存在 tmp.getParentFile().mkdirs();//创建文件父类文件夹路径 OutputStream os = new FileOutputStream(tmp);//将文件目录中的文件放入输出流 //用输入流读取压缩文件中制定目录中的文件 InputStream in = zipFile.getInputStream(entry); int count = 0; while ((count = in.read())!=-1){//如有输入流可以读取到数值 os.write(count);//输出流写入 } os.close(); in.close(); } zin.closeEntry(); System.out.println(entry.getName()+"解压成功"); } zin.close(); } catch (IOException e) { e.printStackTrace(); } } } |
以上代码运行时会抛出异常!!!!!!!!!
做出相应更改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** * date:2019/7/26 * writed by yangtingting */ public class zipUncompress { /** * zip文件解压 * * @param inputFile 待解压文件夹/文件 * @param destDirPath 解压路径 */ public static void zipUncompress(String inputFile, String destDirPath) throws Exception { File srcFile = new File(inputFile);//获取当前压缩文件 // 判断源文件是否存在 if (!srcFile.exists()) { throw new Exception(srcFile.getPath() + "所指文件不存在"); } //开始解压 //构建解压输入流 ZipInputStream zIn = new ZipInputStream(new FileInputStream(srcFile)); ZipEntry entry = null; File file = null; while ((entry = zIn.getNextEntry()) != null) { if (!entry.isDirectory()) { file = new File(destDirPath, entry.getName()); if (!file.exists()) { new File(file.getParent()).mkdirs();//创建此文件的上级目录 } OutputStream out = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(out); int len = -1; byte[] buf = new byte[1024]; while ((len = zIn.read(buf)) != -1) { bos.write(buf, 0, len); } // 关流顺序,先打开的后关闭 bos.close(); out.close(); } } } public static void main(String[] args) { try { zipUncompress("D:\\ytt.zip", "D:\\ytt的解压文件\\"); } catch (Exception e) { e.printStackTrace(); } } } |
完美运行!!!
3.2 zip解压完美实现
改进后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import java.io.*; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * date:2019/7/26 * writed by yangtingting */ public class zipUncompress { /** * zip文件解压 * @param inputFile 待解压文件夹/文件 * @param destDirPath 解压路径 */ public static void zipUncompress(String inputFile,String destDirPath) throws Exception { File srcFile = new File(inputFile);//获取当前压缩文件 // 判断源文件是否存在 if (!srcFile.exists()) { throw new Exception(srcFile.getPath() + "所指文件不存在"); } ZipFile zipFile = new ZipFile(srcFile);//创建压缩文件对象 //开始解压 Enumeration<?> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); // 如果是文件夹,就创建个文件夹 if (entry.isDirectory()) { String dirPath = destDirPath + "/" + entry.getName(); srcFile.mkdirs(); } else { // 如果是文件,就先创建一个文件,然后用io流把内容copy过去 File targetFile = new File(destDirPath + "/" + entry.getName()); // 保证这个文件的父文件夹必须要存在 if (!targetFile.getParentFile().exists()) { targetFile.getParentFile().mkdirs(); } targetFile.createNewFile(); // 将压缩文件内容写入到这个文件中 InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile); int len; byte[] buf = new byte[1024]; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } // 关流顺序,先打开的后关闭 fos.close(); is.close(); } } } public static void main(String[] args) { try { zipUncompress("D:\\ytt.zip","D:\\ytt的解压文件"); } catch (Exception e) { e.printStackTrace(); } } } |
4 FileZip.class 实现.zip压缩与解压
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
import java.io.*; import java.util.zip.*; import java.util.zip.ZipEntry; /** * date: 2019/07/26 * writed by yangtingting */ public class FileZip { /** * zip文件压缩 * @param inputFile 待压缩文件夹/文件名 * @param outputFile 生成的压缩包名字 */ public static void ZipCompress(String inputFile, String outputFile) throws Exception { //创建zip输出流 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile)); //创建缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream(out); File input = new File(inputFile); compress(out, bos, input,null); bos.close(); out.close(); } /** * @param name 压缩文件名,可以写为null保持默认 */ //递归压缩 public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException { if (name == null) { name = input.getName(); } //如果路径为目录(文件夹) if (input.isDirectory()) { //取出文件夹中的文件(或子文件夹) File[] flist = input.listFiles(); if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入 { out.putNextEntry(new ZipEntry(name + "/")); } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩 { for (int i = 0; i < flist.length; i++) { compress(out, bos, flist[i], name + "/" + flist[i].getName()); } } } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中 { out.putNextEntry(new ZipEntry(name)); FileInputStream fos = new FileInputStream(input); BufferedInputStream bis = new BufferedInputStream(fos); int len=-1; //将源文件写入到zip文件中 byte[] buf = new byte[1024]; while ((len = bis.read(buf)) != -1) { bos.write(buf,0,len); } bis.close(); fos.close(); } } /** * zip解压 * @param inputFile 待解压文件名 * @param destDirPath 解压路径 */ public static void ZipUncompress(String inputFile,String destDirPath) throws Exception { File srcFile = new File(inputFile);//获取当前压缩文件 // 判断源文件是否存在 if (!srcFile.exists()) { throw new Exception(srcFile.getPath() + "所指文件不存在"); } //开始解压 //构建解压输入流 ZipInputStream zIn = new ZipInputStream(new FileInputStream(srcFile)); ZipEntry entry = null; File file = null; while ((entry = zIn.getNextEntry()) != null) { if (!entry.isDirectory()) { file = new File(destDirPath, entry.getName()); if (!file.exists()) { new File(file.getParent()).mkdirs();//创建此文件的上级目录 } OutputStream out = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(out); int len = -1; byte[] buf = new byte[1024]; while ((len = zIn.read(buf)) != -1) { bos.write(buf, 0, len); } // 关流顺序,先打开的后关闭 bos.close(); out.close(); } } } public static void main(String[] args) { try { ZipCompress("D:\\Test", "D:\\TestbyYTT.zip"); ZipUncompress("D:\\ytt.zip","D:\\ytt的解压文件"); } catch (Exception e) { e.printStackTrace(); } } } |
转自:https://blog.csdn.net/qq_34474324/article/details/97369763