LoginSignup
24
28

More than 5 years have passed since last update.

Zip4jを使ってパスワード付ZIPファイルを作成するサンプル

Last updated at Posted at 2014-11-09

概要

Zip4jを使ってパスワード付ZIPファイルを作成するサンプルです。

対象のファイルがディレクトリの場合、サブディレクトリも含めて全てのファイルを、階層構造を維持したまま圧縮します。

試した環境

  • jdk 1.8.0_20
  • zip4j 1.3.2

サンプルコード

ZipFileを使う


import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import java.io.IOException;

public class ZipUtil {

    private int compressionMethod = Zip4jConstants.COMP_DEFLATE;
    private int compressionLevel = Zip4jConstants.DEFLATE_LEVEL_NORMAL;
    private int encryptionMethod = Zip4jConstants.ENC_METHOD_STANDARD;
    private int aesKeyStrength = Zip4jConstants.AES_STRENGTH_256;

    public ZipUtil(){
    }

    public ZipUtil(int encryptionMethod, int aesKeyStrength) {
        this.encryptionMethod = encryptionMethod;
        this.aesKeyStrength = aesKeyStrength;
    }

    public void zip(String input, String output, String password)
            throws ZipException, IOException {
        zip(input, output, password, "");
    }

    public void zip(String input, String output, String password, String fileNameCharset)
        throws ZipException, IOException {

        ZipFile zipFile = new ZipFile(output);
        // If the fileNameCharset is empty then charset is detected automatically
        // Try with Cp850 and UTF8 or OS default
        if (!fileNameCharset.isEmpty()) {
            zipFile.setFileNameCharset(fileNameCharset);
        }

        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionMethod(compressionMethod);
        parameters.setCompressionLevel(compressionLevel);
        parameters.setEncryptFiles(true);
        parameters.setEncryptionMethod(encryptionMethod);
        parameters.setAesKeyStrength(aesKeyStrength);
        parameters.setPassword(password);

        File inputFile = new File(input);
        if (inputFile.isDirectory()) {
           zipFile.createZipFileFromFolder(inputFile, parameters, false, 0);
        } else {
           zipFile.addFile(inputFile, parameters);
        }
    }

    public void unzip(String input, String output, String password) throws ZipException {
        ZipFile zipFile = new ZipFile(input);
        if (zipFile.isEncrypted()) {
            zipFile.setPassword(password);
        }
        zipFile.extractAll(output);
    }
}

ZipOutputStreamを使う

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.io.ZipOutputStream;
import net.lingala.zip4j.model.ZipModel;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import java.util.Arrays;
import java.util.LinkedList;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class ZipUtil {

    private int compressionMethod = Zip4jConstants.COMP_DEFLATE;
    private int compressionLevel = Zip4jConstants.DEFLATE_LEVEL_NORMAL;
    private int encryptionMethod = Zip4jConstants.ENC_METHOD_STANDARD;
    private int aesKeyStrength = Zip4jConstants.AES_STRENGTH_256;

    public ZipUtil() {
    }

    public ZipUtil(int encryptionMethod, int aesKeyStrength) {
        this.encryptionMethod = encryptionMethod;
        this.aesKeyStrength = aesKeyStrength;
    }

    public void zip(String input, String output, String password)
            throws ZipException, IOException, CloneNotSupportedException {
        zip(input, output, password, "");
    }

    public void zip(String input, String output, String password, String fileNameCharset)
            throws ZipException, IOException, CloneNotSupportedException {

        ZipModel zipModel = new ZipModel();
        // If the fileNameCharset is empty then charset is detected automatically
        // Try with Cp850 and UTF8 or OS default
        if (!fileNameCharset.isEmpty()) {
            zipModel.setFileNameCharset(fileNameCharset);
        }

        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionMethod(compressionMethod);
        parameters.setCompressionLevel(compressionLevel);
        parameters.setEncryptFiles(true);
        parameters.setEncryptionMethod(encryptionMethod);
        parameters.setAesKeyStrength(aesKeyStrength);
        parameters.setPassword(password);
        parameters.setDefaultFolderPath(new File(input).getParent());

        try (
            ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(new File(output)), zipModel)
        ){
            LinkedList<File> remained = new LinkedList();
            remained.add(new File(input));
            while (!remained.isEmpty()) {
                File file = remained.pollFirst();
                outputStream.putNextEntry(file, (ZipParameters)parameters.clone());
                if (file.isDirectory()) {
                    remained.addAll(0, Arrays.asList(file.listFiles()));
                } else {
                    try (
                        InputStream inputStream = new FileInputStream(file)
                    ){
                        byte[] readBuff = new byte[4096];
                        int readLen = -1;
                        while ((readLen = inputStream.read(readBuff)) != -1) {
                            outputStream.write(readBuff, 0, readLen);
                        }
                    }
                }
                outputStream.closeEntry();
            }
            outputStream.finish();
        }
    }

    public void unzip(String input, String output, String password) throws ZipException {
        ZipFile zipFile = new ZipFile(input);
        if (zipFile.isEncrypted()) {
            zipFile.setPassword(password);
        }
        zipFile.extractAll(output);
    }
}

使用例

// Standard Enc
new ZipUtil().zip("/Users/hoge/file", "/Users/hoge/file.zip", "password");

// AES
new ZipUtil(Zip4jConstants.ENC_METHOD_AES, Zip4jConstants.AES_STRENGTH_256).zip("/Users/hoge/file", "/Users/hoge/file.zip", "password");

// Windowsで作成したファイルを圧縮
new ZipUtil().zip("/Users/hoge/file", "/Users/hoge/file.zip", "password", "windows-31j");

// Unzip
new ZipUtil().unzip("/Users/hoge/file.zip", "/Users/hoge/file", "password");

補足

ファイル名の文字コードについて

ZipModel.fileNameCharsetを指定している場合、指定された文字コードでエンコードする。
指定していない場合、自動判定。CP850, UTF8でエンコード、デコードしてみて元の文字列と一致するか判定する。どちらもあてはまらなければOSのデフォルトを使う。

ソースはこの辺

  • HeaderWriter.writeLocalFileHeader
  • Zip4jUtil.detectCharset

参考

24
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
28