Cyh的博客

Email:kissyan4916@163.com
posts - 26, comments - 19, trackbacks - 0, articles - 220

用Zip格式压缩和解压缩文件

Posted on 2009-05-30 23:36 啥都写点 阅读(489) 评论(0)  编辑  收藏 所属分类: J2SE
关键技术:
  • java.util.zip实现了Zip格式相关的类库,使用ZIP格式压缩和解压缩文件时,需要导入该包。
  • 使用ZipOutputStream可以实现文件压缩,所有写入到ZipOutputStream输出流中的数据,都会被Zip格式压缩。
  • 每个被压缩的文件或者目录在Zip文件中都对应一个ZipEntry对象,每一个ZipEntry都有一个name属性,表示它相对于Zip文件根目录的相对路径,对与目录,路径以“/”结尾,对于文件,路径以文件名结尾。
  • ZipOutputStream的putNextEntry方法往Zip文件中添加一个ZipEntry,紧接着写入到该ZipOutputStream流中数据都被保存在这个ZipEntry种,直到调用ZipOutputStream的closeEntry方法。
  • ZipFile表示一个Zip文件,它的entries方法能获得Zip文件中所有的ZipEntry集合。
  • ZipEntry的isDirctory方法判断该ZipEntry是否代表一个目录。getInputStream方法获得ZipEntry的输入流。

package book.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * 用ZIP压缩和解压缩文件或目录
 
*/
public class CompressUtil {

    
/**
     * 压缩文件或者目录
     * 
@param baseDirName        压缩的根目录
     * 
@param fileName            根目录下待压缩的文件或文件夹名,
     * 星号*表示压缩根目录下的全部文件。
     * 
@param targetFileName    目标ZIP文件
     
*/
    
public static void zipFile(String baseDirName, String fileName, 
            String targetFileName){
        
//检测根目录是否存在
        if (baseDirName == null){
            System.out.println(
"压缩失败,根目录不存在:" + baseDirName);
            
return;
        }
        File baseDir 
= new File(baseDirName);
        
if (!baseDir.exists() || (!baseDir.isDirectory())){
            System.out.println(
"压缩失败,根目录不存在:" + baseDirName);
            
return;
        }
        String baseDirPath 
= baseDir.getAbsolutePath();
        
//目标文件
        File targetFile = new File(targetFileName);
        
try{
            
//创建一个zip输出流来压缩数据并写入到zip文件 
            ZipOutputStream out =new ZipOutputStream(
                    
new FileOutputStream(targetFile)); 
            
if (fileName.equals("*")){
                
//将baseDir目录下的所有文件压缩到ZIP
                CompressUtil.dirToZip(baseDirPath, baseDir, out);
            } 
else {
                File file 
= new File(baseDir, fileName);
                
if (file.isFile()){
                    CompressUtil.fileToZip(baseDirPath, file, out);
                } 
else {
                    CompressUtil.dirToZip(baseDirPath, file, out);
                }
            }
            out.close(); 
            System.out.println(
"压缩文件成功,目标文件名:" + targetFileName);
        } 
catch (IOException e){
            System.out.println(
"压缩失败:" + e);
            e.printStackTrace();
        }
    }

    
/**
     * 解压缩ZIP文件,将ZIP文件里的内容解压到targetDIR目录下
     * 
@param zipName    待解压缩的ZIP文件名
     * 
@param targetBaseDirName    目标目录
     
*/
    
public static void upzipFile(String zipFileName, String targetBaseDirName){
        
if (!targetBaseDirName.endsWith(File.separator)){
            targetBaseDirName 
+= File.separator;
        }
        
try {
            
//根据ZIP文件创建ZipFile对象
            ZipFile zipFile = new ZipFile(zipFileName);
            ZipEntry entry 
= null;
            String entryName 
= null;
            String targetFileName 
= null;
            
byte[] buffer = new byte[4096];
            
int bytes_read; 
            
//获取ZIP文件里所有的entry
            Enumeration entrys = zipFile.entries();
            
//遍历所有entry
            while (entrys.hasMoreElements()) {
                entry 
= (ZipEntry)entrys.nextElement();
                
//获得entry的名字
                entryName =  entry.getName();
                targetFileName 
= targetBaseDirName + entryName;
                
if (entry.isDirectory()){
                    
//  如果entry是一个目录,则创建目录
                    new File(targetFileName).mkdirs();
                    
continue;
                } 
else {
                    
//    如果entry是一个文件,则创建父目录
                    new File(targetFileName).getParentFile().mkdirs();
                }

                
//否则创建文件
                File targetFile = new File(targetFileName);
                System.out.println(
"创建文件:" + targetFile.getAbsolutePath());
                
//打开文件输出流
                FileOutputStream os = new FileOutputStream(targetFile);
                
//从ZipFile对象中打开entry的输入流
                InputStream  is = zipFile.getInputStream(entry);
                
while ((bytes_read = is.read(buffer)) != -1){
                    os.write(buffer, 
0, bytes_read);
                }
                
//关闭流
                os.close( );
                is.close( );
            }
            System.out.println(
"解压缩文件成功!");
        } 
catch (IOException err) {
            System.err.println(
"解压缩文件失败: " + err);
        }
    }
    
    
/**
     * 将目录压缩到ZIP输出流。
     
*/
    
private static void dirToZip(String baseDirPath, File dir, 
            ZipOutputStream out){
        
if (dir.isDirectory()){
            
//列出dir目录下所有文件
            File[] files  = dir.listFiles();
            
// 如果是空文件夹
            if (files.length == 0){
                ZipEntry entry 
= new ZipEntry(getEntryName(baseDirPath, dir));  
                
//    存储目录信息
                try {
                    out.putNextEntry(entry);
                    out.closeEntry();
                } 
catch (IOException e) {
                    e.printStackTrace();
                }
                
return;
            }
            
for (int i=0; i<files.length; i++){
                
if (files[i].isFile()){
                    
//如果是文件,调用fileToZip方法
                    CompressUtil.fileToZip(baseDirPath, files[i], out);
                } 
else {
                    
//如果是目录,递归调用
                    CompressUtil.dirToZip(baseDirPath, files[i], out);
                }
            }
        }
    }
    
/**
     * 将文件压缩到ZIP输出流
     
*/
    
private static void fileToZip(String baseDirPath, File file, 
            ZipOutputStream out){
        FileInputStream in 
= null;
        ZipEntry entry 
= null;
        
//    创建复制缓冲区
        byte[] buffer = new byte[4096];    
        
int bytes_read; 
        
if (file.isFile()){
            
try {
                
// 创建一个文件输入流    
                in = new FileInputStream(file);  
                
//    做一个ZipEntry
                entry = new ZipEntry(getEntryName(baseDirPath, file));  
                
//    存储项信息到压缩文件
                out.putNextEntry(entry);
                
//    复制字节到压缩文件
                while((bytes_read = in.read(buffer)) != -1){  
                    out.write(buffer, 
0, bytes_read); 
                }
                out.closeEntry();
                in.close(); 
                System.out.println(
"添加文件" 
                        
+ file.getAbsolutePath() + "被到ZIP文件中!");
            } 
catch (IOException e){
                e.printStackTrace();
            }
        }
    }
    
/**
     * 获取待压缩文件在ZIP文件中entry的名字。即相对于跟目录的相对路径名
     * 
@param baseDirPath
     * 
@param file
     * 
@return
     
*/
    
private static String getEntryName(String baseDirPath, File file){
        
if (!baseDirPath.endsWith(File.separator)){
            baseDirPath 
+= File.separator;
        }
        String filePath 
= file.getAbsolutePath();
        
// 对于目录,必须在entry名字后面加上"/",表示它将以目录项存储。
        if (file.isDirectory()){
            filePath 
+= "/";
        }
        
int index = filePath.indexOf(baseDirPath);
        
return filePath.substring(index + baseDirPath.length());
    }
    
    
public static void main(String[] args) {
        
//压缩C盘下的temp目录,压缩后的文件是C:/temp.zip
        String baseDirName = "C:/";
        String fileName 
= "temp/";
        String zipFileName 
= "C:/temp.zip";
        CompressUtil.zipFile(baseDirName, fileName, zipFileName);
        
//将刚创建的ZIP文件解压缩到D盘的temp目录下
        System.out.println();
        fileName 
= "D:/temp";
        CompressUtil.upzipFile(zipFileName, fileName);
    }
}


                                                                                                       --    学海无涯
        


只有注册用户登录后才能发表评论。


网站导航: