zip压缩工具类

package com.test.common.util.zipencrypt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.crypto.Cipher;

import com.test.common.util.file.FileUtils;

/**
 * 类描述:提供加密(RSA)压缩功能服务
 *
 *
 * @version v1.0.0 创建时间 2009-4-4 上午11:14:56
 */
public class ZipEncrypt {
    private PrivateKey privateKey = null;
    private PublicKey publicKey = null;

    /**
     * 解压缩文件.
     *
     * @param intputFilePath
     *            要解压缩文件路径及文件名
     * @param outputFilePath
     *            解压缩文件输出路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要解压缩的文件不存在)
     */
    public String unzipFile(String intputFilePath, String outputFilePath) {
        String result = "0";
        boolean b = isExists(intputFilePath);
        if (!b) {
            return "1:要解压缩的文件不存在";
        } else {
            File file = new File(outputFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File outFile = new File(outputFilePath);
            if (!outFile.exists()) {
                outFile.mkdirs();
            }
            unZip(outputFilePath, intputFilePath);
        }
        return result;
    }

    /**
     * 解压缩文件对象.
     *
     * @param intputFile
     *            要解压缩的文件对象
     * @param outputFilePath
     *            解压缩文件输出路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要解压缩的文件格式错误)
     */
    public String unzipFile(File intputFile, String outputFilePath) {
        String result = "0";
        if (intputFile == null) {
            return "1:要解压缩的文件不存在";
        }
        String inFileName = intputFile.getName();
        String endName = inFileName.split("\\.")[1];
        if (!endName.equals("zip")) {
            result = "1:解压缩的文件格式错误";
        } else {
            File file = new File(outputFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            String infile = intputFile.getAbsolutePath();
            unZip(outputFilePath, infile);
            result = "0";
        }
        return result;
    }

    /**
     * 压缩文件.
     *
     * @param intputFilePath
     *            要压缩文件路径及文件名
     * @param outputFilePath
     *            压缩文件输出路径(压缩文件的命名为:原文件名+.zip后缀)
     * @return 0:成功 1:失败+失败原因 (例如:1:要压缩的文件不存在)
     */
    public String zipFile(String intputFilePath, String outputFilePath) {
        String result = "0";
        boolean b = isExists(intputFilePath);
        if (b) {
            File file = new File(intputFilePath);
            result = zipFile(file, outputFilePath);
        } else {
            result = "1:要压缩的文件不存在";
        }
        return result;
    }

    public String zipFile(String intputFilePath, String outputFilePath,
            String name) {
        String result = "0";
        boolean b = isExists(intputFilePath);
        if (b) {
            File file = new File(intputFilePath);
            result = zipFile(file, outputFilePath, name);
        } else {
            result = "1:要压缩的文件不存在";
        }
        return result;
    }

    /**
     * 压缩文件对象.
     *
     * @param intputFile
     *            要压缩的文件对象
     * @param outputFilePath
     *            压缩文件输出路径(压缩文件的命名为:原文件名+.zip后缀)
     * @return 0:成功 1:失败+失败原因 (例如:1:要压缩的文件不存在)
     */
    public String zipFile(File intputFile, String outputFilePath) {
        String result = "0";
        if (intputFile == null) {
            result = "1:要压缩的文件不存在";
        } else {
            File outfile = new File(outputFilePath);
            if (!outfile.exists()) {
                outfile.mkdirs();
            }
            String fileName = intputFile.getName();

            String tempFile = "/" + FileUtils.getFileNameWithoutType(fileName)
                    + ".zip";
            outputFilePath += tempFile;
            String indirectory = intputFile.getAbsolutePath();
            zip(indirectory, outputFilePath);
            return result;
        }
        return result;
    }

    @SuppressWarnings("unused")
    public String zipFile(File intputFile, String outputFilePath, String name) {
        String result = "0";
        if (intputFile == null) {
            result = "1:要压缩的文件不存在";
        } else {
            File outfile = new File(outputFilePath);
            if (!outfile.exists()) {
                outfile.mkdirs();
            }
            String fileName = intputFile.getName();

            String tempFile = name + ".zip";
            outputFilePath += tempFile;
            String indirectory = intputFile.getAbsolutePath();
            zip(indirectory, outputFilePath);
            return result;
        }
        return result;
    }

    /**
     * 解密文件.
     *
     * @param intputFilePath
     *            要解密文件路径及文件名
     * @param outputFilePath
     *            解密文件输出路径
     * @param prikeyPath
     *            私钥文件路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要解密的文件不存在)
     */
    public String decryptFile(String intputFilePath, String outputFilePath,
            String prikeyPath) {
        String result = "0";
        boolean b = isExists(intputFilePath);
        if (!b) {
            return "1:要解密的文件不存在";
        }
        File file = new File(outputFilePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File temp = new File(intputFilePath);

        outputFilePath += "/" + temp.getName();
        try {
            decrypt(intputFilePath, outputFilePath, getKey(prikeyPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 解密文件对象.
     *
     * @param intputFile
     *            解密的文件对象
     * @param outputFilePath
     *            解密文件输出路径
     * @param prikeyPath
     *            私钥文件路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要解密的文件不存在)
     */
    public String decryptFile(File intputFile, String outputFilePath,
            String prikeyPath) {
        String result = "0";
        if (intputFile == null) {
            return "1:要解密的文件不存在";
        }
        File file = new File(outputFilePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        String inFile = intputFile.getAbsolutePath();
        String inName = intputFile.getName();

        outputFilePath += "/" + inName;
        try {
            decrypt(inFile, outputFilePath, getKey(prikeyPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 加密文件.
     *
     * @param intputFilePath
     *            要加密文件路径及文件名
     * @param outputFilePath
     *            加密文件输出路径(加密文件的命名为:原文件名)
     * @param pubkeyPath
     *            公钥文件路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要加密的文件不存在)
     */
    public String encryptFile(String intputFilePath, String outputFilePath,
            String pubkeyPath) {
        String result = "0";
        boolean b = isExists(intputFilePath);
        if (!b) {
            return "1:要加密的文件不存在";
        } else {
            File file = new File(outputFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File tempfile = new File(intputFilePath);

            outputFilePath += "/" + tempfile.getName();
            try {
                encrypt(intputFilePath, outputFilePath, getKey
(pubkeyPath));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 加密文件对象.
     *
     * @param intputFile
     *            要加密的文件对象
     * @param outputFilePath
     *            加密文件输出路径(加密文件的命名为:原文件名)
     * @param pubkeyPath
     *            公钥文件路径
     * @return 0:成功 1:失败+失败原因 (例如:1:要加密的文件不存在)
     */
    public String encryptFile(File intputFile, String outputFilePath,
            String pubkeyPath) {
        String result = "0";
        if (intputFile == null) {
            return "1:要加密的文件不存在";
        } else {
            File file = new File(outputFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            String inpath = intputFile.getAbsolutePath();

            outputFilePath += "/" + intputFile.getName();

            try {
                encrypt(inpath, outputFilePath, getKey(pubkeyPath));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 判断文件是否存在
     *
     * @param inputFilePath
     * @return
     */
    private boolean isExists(String inputFilePath) {
        boolean b = false;
        File tempfile = new File(inputFilePath);
        if (tempfile.exists()) {
            b = true;
        }
        return b;
    }

    /**
     * 目录压缩
     *
     * @param out
     * @param f
     * @param base
     * @throws Exception
     */
    private void directoryZip(ZipOutputStream out, File f, String base)
            throws Exception {
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            out.putNextEntry(new ZipEntry(base + "/"));
            if (base.length() == 0) {
                base = "";
            } else {
                base = base + "/";
            }
            for (int i = 0; i < fl.length; i++) {
                directoryZip(out, fl[i], base + fl[i].getName());
            }
        } else {
            out.putNextEntry(new ZipEntry(base));
            FileInputStream in = new FileInputStream(f);
            byte[] bb = new byte[2048];
            int aa = 0;
            while ((aa = in.read(bb)) != -1) {
                out.write(bb, 0, aa);
            }
            in.close();
        }
    }

    /**
     * 压缩文件
     *
     * @param zos
     * @param file
     * @throws Exception
     */
    private void fileZip(ZipOutputStream zos, File file) throws Exception {
        if (file.isFile()) {
            zos.putNextEntry(new ZipEntry(file.getName()));
            FileInputStream fis = new FileInputStream(file);
            byte[] bb = new byte[2048];
            int aa = 0;
            while ((aa = fis.read(bb)) != -1) {
                zos.write(bb, 0, aa);
            }
            fis.close();
        } else {
            directoryZip(zos, file, "");
        }
    }

    /**
     * 对directory目录下的文件压缩,保存为指定的文件zipFile
     *
     * @param directory
     * @param zipFile
     */
    private void zip(String directory, String zipFile) {
        try {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(
                    zipFile));
            fileZip(zos, new File(directory));
            zos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 压缩byte数组
     *
     * @param fileByte
     * @return
     */
    public byte[] zipByte(byte[] fileByte) {
        byte[] temp = new byte[fileByte.length];
        Deflater compresser = new Deflater();
        compresser.setInput(fileByte);
        compresser.finish();
        int len = compresser.deflate(temp);
        return zipBytecut(fileByte, len);
    }

    private byte[] zipBytecut(byte[] fileByte, int len) {
        byte[] temp = new byte[len];
        Deflater compresser = new Deflater();
        compresser.setInput(fileByte);
        compresser.finish();
        compresser.deflate(temp);
        return temp;
    }

    /**
     * 解压缩byte数组
     *
     * @param fileByte
     * @return
     * @throws Exception
     */
    public byte[] upzipByte(byte[] fileByte, int len) {
        try {
            Inflater decompresser = new Inflater();
            decompresser.setInput(fileByte, 0, fileByte.length);
            byte[] result = new byte[len];
            decompresser.inflate(result);
            decompresser.end();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解压缩文件
     *
     * @param zis
     * @param file
     * @throws Exception
     */
    private void fileUnZip(ZipInputStream zis, File file) throws Exception {
        ZipEntry zip = zis.getNextEntry();
        if (zip == null)
            return;
        String name = zip.getName();
        File f = new File(file.getAbsolutePath() + "/" + name);
        if (zip.isDirectory()) {
            f.mkdirs();
            fileUnZip(zis, file);
        } else {
            f.createNewFile();
            FileOutputStream fos = new FileOutputStream(f);
            byte b[] = new byte[2048];
            int aa = 0;
            while ((aa = zis.read(b)) != -1) {
                fos.write(b, 0, aa);
            }
            fos.close();
            fileUnZip(zis, file);
        }
    }

    /**
     * 解压缩文件zipFile保存在directory目录下
     *
     * @param directory
     * @param zipFile
     */
    private void unZip(String directory, String zipFile) {
        try {
            ZipInputStream zis = new ZipInputStream(
                    new FileInputStream(zipFile));
            File f = new File(directory);
            f.mkdirs();
            fileUnZip(zis, f);
            zis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成密钥对并保存到文件
     *
     * @param keyfile
     */
    public boolean createKey(String priKeyPath, String pubKeyPath) {
        boolean b = false;
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator kg;
        try {
            kg = KeyPairGenerator.getInstance("RSA");
            kg.initialize(512, sr);
            KeyPair kp = kg.generateKeyPair();
            this.privateKey = kp.getPrivate();
            this.publicKey = kp.getPublic();
            File f = new File(priKeyPath); // 保存私钥
            String dir = priKeyPath.replace(f.getName(), "");
            File dirf = new File(dir);
            if (!dirf.exists()) {
                dirf.mkdirs();
            }
            f.createNewFile();
            FileOutputStream fos = new FileOutputStream(f);
            ObjectOutputStream dos = new ObjectOutputStream(fos);
            dos.writeObject(this.privateKey);
            dos.close();
            fos.close();

            File f2 = new File(pubKeyPath); // 保存公钥

            String dir2 = pubKeyPath.replace(f2.getName(), "");
            File dirf2 = new File(dir2);
            if (!dirf2.exists()) {
                dirf2.mkdirs();
            }

            f2.createNewFile();
            FileOutputStream fos2 = new FileOutputStream(f2);
            ObjectOutputStream dos2 = new ObjectOutputStream(fos2);
            dos2.writeObject(this.publicKey);
            dos2.close();
            fos2.close();
            b = true;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return b;
    }

    /**
     * 根据key的路径文件获得持久化成文件的key
     * <P>
     * 例子: ZipEncrypt.getKey("E:/keypath/private.key");
     *
     * @param keyPath
     * @return key
     */
    private Key getKey(String keyPath) throws Exception {
        Key key = null;
        FileInputStream fis = new FileInputStream(keyPath);
        ObjectInputStream ofs = new ObjectInputStream(fis);
        key = (Key) ofs.readObject();
        ofs.close();
        fis.close();
        return key;
    }

    /**
     * 把文件srcFile加密后存储为destFile
     *
     * @param srcFile
     * @param destFile
     * @param privateKey
     * @throws Exception
     */
    private void encrypt(String srcFile, String destFile, Key privateKey)
            throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        byte[] b = new byte[53];
        while (fis.read(b) != -1) {
            fos.write(cipher.doFinal(b));
        }
        fos.close();
        fis.close();
    }

    /**
     * 把文件srcFile解密后存储为destFile
     *
     * @param srcFile
     * @param destFile
     * @param privateKey
     * @throws Exception
     */
    private void decrypt(String srcFile, String destFile, Key privateKey)
            throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        byte[] b = new byte[64];
        while (fis.read(b) != -1) {
            fos.write(cipher.doFinal(b));
        }
        fos.close();
        fis.close();
    }

    /**
     * 对byte数组进行加密
     *
     * @param input
     * @param keyPath
     * @return
     * @throws Exception
     */
    public byte[] encryptByte(byte[] input, String pubKeyPath) {
        try {
            byte[] result = null;
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, (PublicKey) getKey(pubKeyPath));
            ByteArrayInputStream in = new ByteArrayInputStream(input);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] b = new byte[53];
            while (in.read(b) != -1) {
                baos.write(cipher.doFinal(b));
            }
            result = baos.toByteArray();
            baos.close();
            in.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 对byte数组进行解密
     *
     * @param input
     * @param pubKeyPath
     * @return
     * @throws Exception
     */
    public byte[] decryptByte(byte[] input, String priKeyPath) {
        try {
            byte[] result = null;
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, (PrivateKey) getKey(priKeyPath));
            ByteArrayInputStream in = new ByteArrayInputStream(input);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] b = new byte[64];
            while (in.read(b) != -1) {
                baos.write(cipher.doFinal(b));
            }
            result = baos.toByteArray();
            baos.close();
            in.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 对目录srcFile下的所有文件目录进行先压缩后加密,然后保存为destfile
     *
     * @param srcFile
     *            要操作的目录,如: "E:/srcFile"
     * @param destfile
     *            压缩加密后存放的文件名,如: "E:/destfile.zip"
     * @param keyfile
     *            公钥存放地点
     */
    public void encryptZip(String srcFile, String destfile, String keyfile)
            throws Exception {
        File temp = new File(UUID.randomUUID().toString() + ".zip");
        temp.deleteOnExit();
        zip(srcFile, temp.getAbsolutePath());// 先压缩文件
        encrypt(temp.getAbsolutePath(), destfile, publicKey);// 对文件加密
        temp.delete();
    }

    /**
     * 对文件srcfile进行先解密,然后解压缩到目录destfile下
     *
     * @param srcfile
     *            要解密和解压缩的文件名,如: "E:/srcfile.zip"
     * @param destfile
     *            解压缩后的目录,如: "E:/destfile"
     * @param publicKey
     *            公钥
     */
    public void decryptUnzip(String srcfile, String destfile, Key publicKey)
            throws Exception {
        File temp = new File(UUID.randomUUID().toString() + ".zip");
        temp.deleteOnExit();
        decrypt(srcfile, temp.getAbsolutePath(), publicKey); // 先对文件解密
        unZip(destfile, temp.getAbsolutePath());// 解压缩
        temp.delete();
    }
    public static void main(String[] args) {
        ZipEncrypt encrypt=new ZipEncrypt();
        encrypt.zipFile("E://zip.txt","E://zip");
    }
}


猜你喜欢

转载自blog.csdn.net/SmCai/article/details/7763462