java实现简单压缩与解压缩功能

ZIP是一种很常见的压缩形式,在java中要实现ZIP的压缩主要用到的是 java.util.zip这个包里面的类。
这个包里主要有ZipFile、 ZipOutputStream、ZipInputStream和ZipEntry这几个类。
ZipOutputStream是用来压缩文件 的,ZipInputStream和ZipFile是用来解压缩文件的,在压缩和解压缩的过程中,ZipEntry都会用到。在java的Zip压缩文件 中,每一个子文件都是一个ZipEntry对象。
来看这几个类:
1、 ZipOutputStream:
构造方法:
    ZipOutputStream ( OutputStream  out)   创建新的 ZIP 输出流。
常用方法:
void close()  关闭 ZIP 输出流和正在过滤的流。   
void putNextEntry(ZipEntry e) 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
void setComment(String comment) 设置 ZIP 文件注释。 
void write(byte[] b, int off, int len) 将字节数组写入当前 ZIP 条目数据。
2. ZipInputStream
构造方法:
    ZipInputStream ( InputStream  in)  创建新的 ZIP 输入流。
常用方法:
 void close() 关闭此输入流并释放与此流关联的所有系统资源。  
ZipEntry getNextEntry() 读取下一个 ZIP 文件条目并将流定位到该条目数据的开始处。
int read(byte[] b, int off, int len) 从当前 ZIP 条目读入字节数组。
3.ZipFile(此类用于从 ZIP 文件读取条目。)
构造方法:
ZipFile(File file)
          打开供阅读的 ZIP 文件,由指定的 File 对象给出。
ZipFile(File file, int mode)
          打开新的 ZipFile 以使用指定模式从指定 File 对象读取。
ZipFile(String name)
          打开 ZIP 文件进行阅读。
常用方法:
void close()
          关闭 ZIP 文件。
Enumeration<? extends ZipEntry> entries()
          返回 ZIP 文件条目的枚举。
ZipEntry getEntry(String name)
          返回指定名称的 ZIP 文件条目;如果未找到,则返回 null。
InputStream getInputStream(ZipEntry entry)
          返回输入流以读取指定 ZIP 文件条目的内容。
String getName()
          返回 ZIP 文件的路径名。
int size()
          返回 ZIP 文件中的条目数。
下面通过一个例子熟悉ZipFile类中几个常用方法的作用,关于ZipInputStream和ZipOutputStream的用法放在后面压缩解压缩测试中:
 
 
 
 
public static void ZipFileDemo(File zipFile) throws ZipException, IOException
    {
        ZipFile zf = new ZipFile(zipFile);//创建ZipFile对象
        int size = zf.size();//返回ZIP 文件中的条目数
        Enumeration<? extends ZipEntry> en = zf.entries();//枚举压缩文件中的条目数
        System.out.println("压缩文件中包含以下文件:");
        while(en.hasMoreElements())//遍历
        {
            ZipEntry zipEntry = en.nextElement();
            System.out.println(zipEntry.getName());//输出压缩文件中每个条目的名称
        }
        System.out.println("ZIP 文件中的条目数,size = " + size);
        System.out.println("压缩文件名:" + zf.getName());
    } 

main方法中调用之:
ZipFileDemo(new File("f:\\demo.zip")); 

输出:
压缩文件中包含以下文件:
1.txt
2.txt
3.txt
4.txt
5.txt
6.txt
ZIP 文件中的条目数,size = 6
压缩文件名 :f :\demo.zip
 
下面我们通过一个简单的例子实现压缩与解压缩的功能:
package zip;
import java.io.BufferedInputStream;
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.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipTest
{
    public static void main(String[] args)
    {
        // TODO 自动生成的方法存根
        try
        {
            zipSingleFile("f:\\data.zip",new File("f:\\demo\\data.mp3"));
            freeSingleFile("f:\\data.zip");
        }
        catch (IOException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
    //压缩单个文件
    public static void zipSingleFile(String zipName,File file) throws IOException
    {
        
        BufferedInputStream bufi = 
                new BufferedInputStream(new FileInputStream(file));//创建输入流对象,用来读取文件内容
        
        ZipOutputStream zo = 
                new ZipOutputStream(new FileOutputStream(new File(zipName)));//创建ZipOutputStream对象,用来压缩文件
        ZipEntry ze = new ZipEntry(file.getName());//使用指定名称创建新的 ZIP条目
        zo.putNextEntry(ze);//开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。
        
        int len = 0;
        byte[] b = new byte[1024];
        System.out.println("正在压缩....");
        while((len = bufi.read(b)) != -1)
        {
            zo.write(b, 0, len);//将读取的字节数组写入压缩文件中
        }
        System.out.println("压缩完成!");
        zo.close();
        bufi.close();
    }
    public static void freeSingleFile(String zipName) throws ZipException, IOException
    {
        System.out.println("正在解压缩....");
        ZipFile zf = new ZipFile(new File(zipName));//创建ZipFile对象
        
        ZipInputStream zi = new ZipInputStream(new FileInputStream(zipName));//创建ZipInputStream对象,并绑定一个压缩文件
        
        ZipEntry zipEntry = null; 
        
        while((zipEntry = zi.getNextEntry()) != null)//遍历压缩文件中的每个条目并操作之
        {
            String filename = zipEntry.getName();
            File temp = new File("f:\\unpackTest\\" + filename);//创建一个File对象用来存放解压缩后的文件
            if (! temp.getParentFile().exists()) //判断路径"f:\\unpackTest\\"是否存在,不存在就创建(默认不自动创建该目录)
                 temp.getParentFile().mkdirs(); 
            
             OutputStream out = new FileOutputStream(temp);
             InputStream in = zf.getInputStream(zipEntry);//返回输入流以读取指定 ZIP 文件条目的内容。
             
             int len = 0;
             byte[] buffer = new byte[1024];
             while((len = in.read(buffer)) != -1)
             {
                 out.write(buffer,0,len);//解压缩
             }
             out.close();
             in.close();
             System.out.println("解压缩文件成功...");
        }
    }
} 

freeSingleFile方法也可以这样写(用枚举):
public static void freeSingleFile_2(String zipName) throws ZipException, IOException
    {
        System.out.println("正在解压缩....");
        ZipFile zf = new ZipFile(new File(zipName));//创建ZipFile对象
        
        Enumeration<? extends ZipEntry> en = zf.entries();
        while(en.hasMoreElements())
        {
            ZipEntry ze = en.nextElement();
            String filename = ze.getName();
            File temp = new File("f:\\unpackTest\\" + filename);//创建一个File对象用来存放解压缩后的文件
            if (! temp.getParentFile().exists()) //判断路径"f:\\unpackTest\\"是否存在,不存在就创建(默认不自动创建该目录)
                temp.getParentFile().mkdirs(); 
            
             OutputStream out = new FileOutputStream(temp);
             InputStream in = zf.getInputStream(ze);//返回输入流以读取指定 ZIP 文件条目的内容。
             
             int len = 0;
             byte[] buffer = new byte[1024];
             while((len = in.read(buffer)) != -1)
             {
                 out.write(buffer,0,len);//解压缩
             }
             out.close();
             in.close();
             System.out.println("解压缩文件成功...");
        }
    } 

假如一个文件夹中含有多个文件,怎样压缩呢?我们可以通过遍历文件的方式压缩每一个条目:
package zip;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Zips
{
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO 自动生成的方法存根
        try
        {
            zip("f:\\data.zip",new File("f:\\demo"));
        }
        catch (IOException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
    public static void zip(String zipName,File file) throws IOException
    {
        ZipOutputStream zo = 
                new ZipOutputStream(new FileOutputStream(new File(zipName)));//全局公用一个 ZipOutputStrea对象!
        
        zip(zipName,file,zo);
        zo.close();
    }
    public static void zip(String zipName, File file,ZipOutputStream zo) 
            throws IOException
    {
        if(!file.isDirectory())
        {
            BufferedInputStream bufi = 
                    new BufferedInputStream(new FileInputStream(file));
            ZipEntry ze = new ZipEntry(file.getName());
            zo.putNextEntry(ze);// 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。
            int len = 0;
            byte[] b = new byte[1024];
            System.out.println("正在压缩....");
            while ((len = bufi.read(b)) != -1)
            {
                zo.write(b, 0, len);// 将读取的字节数组写入压缩文件中
            }
            System.out.println("压缩完成!");
            zo.closeEntry();
        }
        else
        {
            File[] files = file.listFiles();//遍历
            for(File fi : files)
            {
                zip(zipName,fi,zo);//递归调用
            }
        }
    }
} 

注意:
1.以上代码还很不完善,不能在实际项目中使用,仅仅是对java自带压缩的简单使用的介绍。
2.jdk自带压缩的api并不完美,存在中文不支持等问题,建议使用第三方的api,具体请google之。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值