压缩文件的解决方法

一、解压文件

1、解压zip格式的文件

public class Demo02 {
    public static void main(String[] args) {
        String path="D:\\IO流\\easyftp-server-1.7.0.10-cn.zip";
        unzip(path);
    }
    public static void unzip(String path){
        //根据压缩包所在路径创建一个File对象,以便于后期解压文件的存储和命名:
        File sourceFile=new File(path);
        //获取源文件(压缩包)的名称
        String sourceFileName=sourceFile.getName();      
        //获取根目录并创建一个新的文件对象
        //D:\\IO流\\easyftp-server-1.7.0.10-cn
        String root=sourceFile.getParent()+"\\"+sourceFileName.substring(0,
                                                 sourceFileName.lastIndexOf("."));
        File rootDir=new File(root);

        //判断根目录是否已经存在
        if(rootDir.exists()){
            //若存在,则删除
            try{
                FileUtils.deleteDirectory(rootDir);
            }catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
        //创建根目录
		rootDir.mkdir();
    }
}
        

        

        //为什么这里删除目录时要用: FileUtils.deleteDirectory(rootDir);而不用rootDir.delete();呢?

我们尝试用delete()方法,发现目录并没有被删除,是因为delete()方法只能删除空目录,所以我们使用了commons-io包提供的FileUtils工具进行删除。

        //运行后我们可以看到在相同路径下我们已经建好了一个和压缩包名称相同的目录:

//但是目录中并没有内容,所以我们:

public static void unzip(String path) {
    //...
    //创建zipInputStream对象,用于读取zip压缩文件格式
   try (ZipInputStream in=new ZipInputStream(new FileInputStream(sourceFile));){
        //遍历压缩包中的每一个子目录或子文件(ZipEntry类型的对象)
        ZipEntry zipEntry=null;
        While((zipEntry=in.getNextEntry())!=null){
            //创建子目录或文件
            File file=new File(rootDir.getPath()+"\\"+zipEntry.getName());
            if(zipEntry.isDirectory()) {
				//创建新子目录
				file.mkdir();
			}else {
				//创建新子文件
				file.createNewFile();
            }
        }
    }catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}

         //“zip”格式的压缩文件中每一个子文件和子目录都是ZipEntry类的,所以通过zipEntry=in.getNextEntry()来遍历压缩文件中的子文件和子目录

        //运行后可以看到,我们刚刚创建的目录easyftp-server-1.7.0.10-cn中有了子文件和子目录:

//但是子目录和子文件中也是空的,所以我们接下来将压缩包中的内容写入:

public static void unzip(String path) {
    //...
    else {
		//创建新子文件
		file.createNewFile();
					
		//读取当前压缩包的子文件,并通过输出流out写入新的子文件
        try(FileOutputStream out=new FileOutputStream(file);){
            byte[] buff=new byte[1024];
            int len=-1;
            while((len=in.read(buff))!=-1){
				out.write(buff,0,len);
			}
                }
				    }
			            }
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        //运行后,我们可以看到文件中有内容了,到此解压成功:

2、解压rar格式的文件

        上面的方法只能压缩“zip”格式的压缩文件,那么对于“rar”格式的文件,我们可以直接将"rar"后缀名改成“zip”,然后用上述方法解压,还可以通过以下方法,专门解压"rar"文件:

public class Demo02 {
	public static void main(String[] args) {
       String path="D:\\IO流\\实验案例.rar"; 
       if(path.endsWith(".zip")) {
        unzip(path);
	   }
	   else if(path.endsWith(".rar")) {
        unrar(path);
	   }
    }
    //1.解压rar格式
    public static void unrar(String path) {
		File rarFile=new File(path);
        //获取根目录并创建一个新的文件对象
        File rootDir=new File(rarFile.getParent()+
                        "\\"+rarFile.getName()
                        .substring(0,rarFile.getName()
                        .lastIndexOf(".")));
        if(rootDir.exists()) {
			try {
				FileUtils.deleteDirectory(rootDir);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
        //创建根目录
        rootDir.mkdir();
        //创建Archive对象,用于读取rar压缩文件格式
        //等同于上述案例中的ZipInputStream
        try(Archive archive=new Archive(new FileInputStream(path)))
            //获取压缩文件中的所有子目录或文件(FileHeader对象)
            List<FileHeader> fileheaderList=archive.getFileHeaders();
            //输出所有子文件和子目录我们发现和原文件的顺序不一样,所以无法        
            创建出子解压文件中的文件和子目录
            //所以我们需要对fileheaderList中的子文件和目录名进行排序
            @Override
				public int compare(FileHeader o1, FileHeader o2) {
					// TODO Auto-generated method stub
					return o1.getFileName().compareTo(o2.getFileName());
				}
        });
        //遍历子目录和子文件
        for(FileHeader fd:fileheaderList){
            File f=new File(rootDir.getPath()+"\\"+fd.getFileName());
            if(fd.isDirectory()) {
				f.mkdir();
			}else {
				f.createNewFile();
                
                //获取压缩包中的子文件输入流  
                InputStream in=archive.getInputStream(fd)
                //复制文件输入流至新的子文件
				FileUtils.copyInputStreamToFile(in, f);
            }
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RarException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			
		
	}

 //“rar”格式的压缩文件中每一个子文件和子目录都是FileHeader类的,所以通过将所有子文件和子目录存进一个lIst集合中,然后用FileUtils类中copyInputStream()方法一次性将他们全部复制到创建好的目录和文件中

二、压缩文件

        ZipOutStream是一种FilterOutputStream,它可以直接 将内容写入到压缩包

public class Demo05 {
	public static void main(String[] args) {
        //原始文件所在目录
        File dir=new File("C:\\Users\\卫小佳\\Desktop\\数据结构");

        //获取所有原始子文件
		File[] files=dir.listFiles();

        //创建zip压缩文件的输出流
        try(ZipOutputStrteam out=new ZipOutputStrteam(new 
                                    FileOutputStream(dir.getParent()+
                                    "\\"+dir.getName()+".zip"))){
            //遍历所有原始子文件
            for(File f:files) {
				//写入一个压缩包中的子文件(ZipEntry对象)
                out.putNextEntry(new ZipEntry(f.getName()));
                //写入字节内容
				out.write(Files.readAllBytes(f.toPath()));
                //关闭压缩包中的子文件
				out.closeEntry();
            }
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值