使用Java进行文件压缩

         在web开发过程中,进行文件的压缩传输是一种常见的需求。比如一种场景:用户需要下载定时生成的报表,我们需要先对报表文件进行压以方便用户的下载,并减少文件的存储空间。
         事实上,JDK已经提供了文件压缩/解压缩的支持,可以生成zip/gzip的压缩格式,并且支持支持“校验和”以检查压缩文件的完整性。通常会使用CRC(循环冗余校验)算法进行校验。

         遗憾的是,JDK的文件压缩功能无法处理文件名称包含中文的问题。为此,我们需要用到ant.jar第三方开源支持包。

          如下所示代码,采用Junit 4进行压缩功能的测试:

 

/*
 * Copyright (c) 2014, hello_nick_xu@foxmail.com, All rights reserved.
 */
package com.test.zip;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.junit.Test;

/**
 * 功能简述: 进行文件压缩功能测试
 * @author Nick Xu
 */
public class ZipTest {
    //源文件夹
	private final String sourceDirStr = "E:/source";
	//目标文件
	private final String zipPath = "E:/dest.zip";
	//缓冲区大小设置
	private static final int BUFFER_SIZE = 1024;

	/** 
	 * 功能简述: 普通压缩测试
	 * @throws Exception
	 */
	@Test
	public void testZip() throws Exception {

		// zip输出流:使用缓冲流进行了包装
		ZipOutputStream zipOut = new ZipOutputStream(
		    new BufferedOutputStream(
				new FileOutputStream(zipPath), BUFFER_SIZE));

		// 得到源文件夹下的文件列表
		File sourceDirectory = new File(sourceDirStr);
		File[] files = sourceDirectory.listFiles();

		byte[] bs = new byte[BUFFER_SIZE];    // 缓冲数组
		int value = -1;   //文件是否结束标记
		
		for (File file : files) { // 遍历所有的文件
			zipOut.putNextEntry(new ZipEntry(file.getName()));   // 存入文件名称,便于解压缩
		    //文件读写
			BufferedInputStream bfInput = new BufferedInputStream(
					new FileInputStream(file), BUFFER_SIZE);
			while ((value = bfInput.read(bs, 0, bs.length)) != -1) {
				zipOut.write(bs, 0, value);
			}
			bfInput.close(); //关闭缓冲输入流
		}
		//关闭输出流
		zipOut.flush();
		zipOut.close();
	}
	
	/** 
	 * 功能简述: 文件压缩测试,获取校验和
	 * @throws Exception
	 */
	@Test
	public void testZipWithCheckSum() throws Exception {

		//被校验的输出流:使用CRC32校验算法
		CheckedOutputStream checkedOutput = new 
		    CheckedOutputStream(new BufferedOutputStream(
				new FileOutputStream(zipPath), BUFFER_SIZE),new 
			    CRC32());
		//使用ZipOutputStream进行包装
		ZipOutputStream zipOut = new ZipOutputStream(checkedOutput);

		// 得到文件名称列表
		File sourceDirectory = new File(sourceDirStr);
		File[] files = sourceDirectory.listFiles();

		// 读写文件
		byte[] bs = new byte[BUFFER_SIZE];
		int value = -1;
		for (File file : files) {
			BufferedInputStream bfInput = new BufferedInputStream(
					new FileInputStream(file), BUFFER_SIZE);
			zipOut.putNextEntry(new ZipEntry(file.getName()));
			while ((value = bfInput.read(bs, 0, bs.length)) != -1) {
				zipOut.write(bs, 0, value);
			}
			bfInput.close();
		}
		zipOut.flush();
		zipOut.close();
		
		//获取校验和:用于校验文件的完整性
		long checkSum = checkedOutput.getChecksum().getValue();
		System.out.println("checkSum : " + checkSum);
	}
}

 完整项目功能,参见附件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值