`
yixiandave
  • 浏览: 140569 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java生成zip压缩文件

阅读更多
jdk自身有zip相关的代码,不过直到1.6的版本没有提供设置字符集的接口,因此都会出现中文乱码,目前网上的方案大多需要引入ant包进行处理:

//创建org.apache.tools.zip.ZipOutputStream
ZipOutputStream zos = new ZipOutputStream(cos);
zos.setEncoding("gbk");


然而,1.7已经修复了这个问题

在jdk7中的java.util.zip.ZipOutputStream新增了这样一个构造方法:
    /**
     * Creates a new ZIP output stream.
     *
     * @param out the actual output stream
     *
     * @param charset the {@linkplain java.nio.charset.Charset charset}
     *                to be used to encode the entry names and comments
     *
     * @since 1.7
     */
    public ZipOutputStream(OutputStream out, Charset charset) {
        super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
        if (charset == null)
            throw new NullPointerException("charset is null");
        this.zc = ZipCoder.get(charset);
        usesDefaultDeflater = true;
    }

这就为我们设置字符集提供了接口

ZipOutputStream zos = new ZipOutputStream(cos, Charset.forName("gbk"));


这样一来两个方法基本来说可以算是等效了,后面的新增文件方法都相同的
给一个使用jdk自带ZipOutputStream的直接取得zip文件字节数组的方案


import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created with IntelliJ IDEA.
 * User: yixian
 * Date: 13-10-17
 * Time: 下午2:52
 * 将文件夹压缩并取回zip文件byte[]
 */
public class DefaultZipper implements IZipper {
    private Set<String> filePathSet = new HashSet<String>();
    private File targetFile;
    private Logger logger = LoggerFactory.getLogger(getClass());

    public DefaultZipper() {
        String tempDirectory = FileUtils.getTempDirectoryPath();
        if (!tempDirectory.endsWith(File.separator)) {
            tempDirectory += File.separator;
        }
        targetFile = initRandomTarget(tempDirectory);
    }

    private synchronized File initRandomTarget(String tempDirectory) {
        File target;
        do {
            String fileName = RandomStringUtils.random(20, true, true);
            String targetFilePath = tempDirectory + fileName;
            target = new File(targetFilePath);
        } while (target.exists());
        return target;
    }

    private boolean checkFilePath(String path) {
        File file = new File(path);
        return file.exists();
    }

    @Override
    public boolean addFile(String filePath) {
        if (checkFilePath(filePath)) {
            filePathSet.add(filePath);
            return true;
        }
        return false;
    }

    @Override
    public String[] addFiles(String... paths) {
        String[] notExistsFiles = new String[0];
        for (String path : paths) {
            if (!addFile(path)) {
                ArrayUtils.add(notExistsFiles, path);
            }
        }
        return notExistsFiles;
    }

    @Override
    public byte[] doCompress() throws IOException {
        FileOutputStream fos = new FileOutputStream(targetFile);
        CheckedOutputStream cos = new CheckedOutputStream(fos, new CRC32());
        ZipOutputStream zos = new ZipOutputStream(cos, Charset.forName("gbk"));
        String baseDir = "";
        for (String filePath : filePathSet) {
            compress(new File(filePath), zos, baseDir);
        }
        zos.close();
        return loadTargetFileBytes();
    }

    private void compress(File file, ZipOutputStream zos, String basePath) {
        if (file.isDirectory()) {
            logger.debug("compressing dir:" + basePath + file.getName());
            compressDirectory(file, zos, basePath);
        } else {
            logger.debug("compressing file:" + basePath + file.getName());
            compressFile(file, zos, basePath);
        }
    }

    private void compressDirectory(File dir, ZipOutputStream zos, String basePath) {
        File[] childrenFiles = dir.listFiles();
        for (File child : childrenFiles != null ? childrenFiles : new File[0]) {
            compress(child, zos, basePath + dir.getName() + "/");
        }
    }

    private void compressFile(File file, ZipOutputStream zos, String basePath) {
        if (!file.exists()) {
            return;
        }
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            String entryName = basePath + file.getName();
            ZipEntry entry = new ZipEntry(entryName);
            zos.putNextEntry(entry);
            byte[] buffer = FileUtils.readFileToByteArray(file);
            zos.write(buffer);
            zos.flush();
            zos.closeEntry();
            bis.close();
        } catch (IOException ignored) {
        }
    }

    private byte[] loadTargetFileBytes() {
        try {
            byte[] fileBytes = FileUtils.readFileToByteArray(targetFile);
            boolean deleted = targetFile.delete();
            logger.debug("file:" + targetFile.getAbsoluteFile() + " deleted:" + deleted);
            return fileBytes;
        } catch (IOException e) {
            return new byte[0];
        }
    }
}



引入了两个commons包,给出Maven Dependency
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>


测试:
import com.skytech.crius.city.util.DefaultZipper;
import org.junit.Test;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: yixian
 * Date: 13-10-21
 * Time: 上午10:30
 */
public class ZipTest {
    private static final String SOURCE_FILE_PATH = "d:\\foo\\bar";
    @Test
    public void DefaultZipperTest() throws IOException {
        IZipper zipper = new DefaultZipper();
        zipper.addFile(SOURCE_FILE_PATH);
        byte[] bytes = zipper.doCompress();
        FileOutputStream fos = new FileOutputStream("d:\\test.zip");
        fos.write(bytes);
        fos.flush();
        fos.close();
    }
}


注意这个案例因为要把zip压缩文件整体读入内存所以如果压的文件体积太大就会......
0
1
分享到:
评论
2 楼 yixiandave 2013-10-23  
zhuchao_ko 写道
org.apache.tools.zip.*

这个轮子比你的好。


这里只是给个DEMO,不是造轮子
对于jdk1.6以前的版本来说,要对中文zip支持就要用ant的包(可能也有其他的开源包)

但是jdk1.7已经修复了强制设置UTF8字符集的bug,第二段代码只是对jdk内的源码进行摘录
1 楼 zhuchao_ko 2013-10-23  
org.apache.tools.zip.*

这个轮子比你的好。

相关推荐

    java 生成zip压缩文件

    在Java编程语言中,生成ZIP压缩文件是一项常见的任务,它涉及到文件操作和数据...总的来说,Java生成ZIP压缩文件涉及到了IO流、文件操作和压缩算法的理解,熟练掌握这些知识点能帮助你更高效地处理文件归档和数据传输。

    基于Java向zip压缩包追加文件

    在Java编程中,向现有的ZIP压缩包追加文件通常需要经过解压、修改、再压缩的步骤,因为标准的Java ZIP库(如`java.util.zip`包)并不直接支持追加到已存在的ZIP文件。本篇文章将深入探讨如何实现这个功能,主要关注...

    java生成.zip包,解压缩.zip

    最后,`生成zip包代码.txt`和`解压缩zip包.txt`文件可能包含了具体的实现代码,而`需要用的jar包`可能是指在某些情况下,如使用第三方库时,可能需要引入额外的依赖项。例如,如果使用了Apache Commons Compress库,...

    java压缩文件生成带密码的zip包,解压带密码的zip包的工具类

    * @param zipFile 指定的ZIP压缩文件 * @param dest 解压目录 * @param passwd ZIP文件的密码 * @return 解压后文件数组 * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 */ 方法详细见文件! 一个...

    java生成PDF 然后加密压缩文件

    前段时间由于项目需要,使用java生成PDF文件,然后将文件压缩成ZIP格式,同时对压缩文件进行加密,先将代码及jar包上传供大家参考,并希望大家共同完善和学习。 java生成PDF,java加密压缩文件并,java生成PDF后压缩...

    java后台批量下载文件并压缩成zip下载的方法

    在Java后台中,批量下载文件压缩成zip下载可以使用Java的文件输入输出流和zip压缩流来实现。首先,需要在Servlet中获取文件列表,然后使用循环将文件一个个添加到zip文件中,最后下载zip文件到本地桌面。 java批量...

    java如何生成压缩文件jar.zip

    在Java编程环境中,生成压缩文件,如`.jar`或`.zip`,是常见的需求,尤其在打包和分发应用程序时。下面将详细讲解如何使用Java来创建`.jar`和`.zip`格式的压缩文件。 首先,`.jar`文件是Java档案(Java Archive)...

    java压缩文件源码--ZipUtils

    // 设置压缩文件入口entry,为被读取的文件创建压缩条目 File tempFile = new File(fileArray[i].toString()); String rootStr = file.getPath(); String entryStr = null; // entry以相对路径的...

    使用Java向服务器上传文件压缩包并实现解压缩

    在这个场景中,我们关注的是如何使用Java来实现文件压缩包的上传以及在服务器上的解压缩。Java作为一种强大的编程语言,提供了丰富的库来支持这样的操作,特别是在涉及到SFTP(Secure File Transfer Protocol)时,...

    Java实现将多目录多层级文件打成ZIP包,以及解压ZIP包

    这个库简化了在Java中处理压缩文件的过程,提供了丰富的API供开发者使用。 首先,我们来看`FileUtils.java`中的主要方法。通常,这个类会包含两个核心功能:`zipFiles()`用于创建ZIP包,`unzipFile()`用于解压ZIP包...

    zip带密码压缩解压缩工具类(java)

    在Java编程环境中,处理压缩和解压缩文件是一项常见的任务,特别是在数据传输、文件备份或存储优化等场景。本文将深入探讨如何使用`zip4j`库来实现带密码的ZIP文件压缩与解压缩,该库支持中文文件名,并且具有良好的...

    java生成PDF,java加密压缩文件

    前段时间由于项目需要,使用java生成PDF文件,然后将文件压缩成ZIP格式,同时对压缩文件进行加密,先将代码及jar包上传供大家参考,并希望大家共同完善和学习。 java生成PDF,java加密压缩文件并,java生成PDF后压缩...

    java压缩文件以及文件夹

    总之,`ZipCompressor.java`是实现文件和文件夹压缩的关键类,它利用了Java标准库提供的`ZipOutputStream`和`ZipEntry`,通过一系列的步骤,将原始文件和目录打包成ZIP格式的压缩文件。熟悉这些概念和API,开发者就...

    java POI生成word.zip

    在本案例中,"java POI生成word.zip"是一个压缩包,包含使用Java POI库生成Word文档的示例代码。以下是基于这个主题的相关知识点: 1. **Java POI库介绍** - Java POI 是一套API,用于处理Microsoft Office格式的...

    将文件进行zip压缩并base64加密和解密

    ZIP是一种流行的文件格式,用于将一个或多个文件打包成一个单一的压缩文件,以节省存储空间和提高传输效率。在Java中,我们可以使用`java.util.zip`包中的`ZipOutputStream`和`ZipEntry`类来实现文件的压缩。以下是...

    利用Java实现zip压缩解压缩

    - **`ZipOutputStream`**:用于创建 ZIP 格式的压缩文件。 - **构造方法**: - `public ZipOutputStream(OutputStream out)`: 构造一个指向指定 `OutputStream` 的 `ZipOutputStream` 对象。 - **常用方法**: -...

    windows 下java调用winrar压缩文件为rar 格式

    要在Java中处理RAR格式的压缩文件,由于Java标准库不直接支持RAR格式,我们需要引入第三方库。一个常用的库是`com.igormaznitsa:nativesharp-jni`,它封装了WinRAR的API,使得Java可以调用WinRAR的功能。安装该库后...

    java+pdf生成.zip

    Java生成PDF文件是一种常见的技术需求,特别是在开发报告生成、电子发票、文档自动化等领域。PDF(Portable Document Format)格式因其跨平台、保持原始样式的特点而被广泛使用。在Java环境中,有多个库可以帮助...

    java 下载文件 压缩且删除源文件(支持文件夹与文件)

    zip,然后下载删除源文件与压缩文件。 3、可以指定文件都为最后生成为zip文件下载,且删除源文件。 1、压缩文件或者目录(只是压缩不删除):zipFileOrDirectory 2、程序自动判断如果是文件那么就是源文件下载,...

    CSV文件生成及Z压缩成zip下载

    分步生成csv,获取数据第一行生成文件标题,同时生成第一行数据,返回标题名称。 将多csv文件压缩成zip,之后删除原csv文件

Global site tag (gtag.js) - Google Analytics