用Java代碼實現文件的壓縮

從網上找的一些別人寫的代碼,自己重新寫了一下。這是Java自帶的不支持中文。密碼暫時只支持三個字符的密碼。

如果要實現中文格式的文檔壓縮解壓縮就要用

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

來替換。這是ant.jar中的。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

public class Zip {
	private static final int SIZE = 1024;
	private static final String algorithm = "PBEWithMD5AndDES";
	
	public void compressing(File from, File to) throws Exception {
		compressAndPwd(from, to, null);
	}

	public void compressAndPwd(File from, File to, String pwd) throws Exception {
		ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(to));
		BufferedOutputStream toOut = new BufferedOutputStream(zipOutputStream, SIZE);
		compressing(zipOutputStream, from, from.getName(), toOut, pwd);
		zipOutputStream.close();
		toOut.close();
	}

	public void compressing(ZipOutputStream zipOutputStream, File from, String base, BufferedOutputStream toOut, String pwd) throws Exception {
		if (from.isDirectory()) {
			zipOutputStream.putNextEntry(new ZipEntry(base + "/"));
			File[] files = from.listFiles();
			if (files.length == 0) {
				base = "";
			} else {
				base += "/";
			}
			for (int i = 0; i < files.length; i++) {
				compressing(zipOutputStream, files[i], base + files[i].getName(), toOut, pwd);
			}
			zipOutputStream.closeEntry();
		} else {
			zipOutputStream.putNextEntry(new ZipEntry(base));
			FileInputStream in = new FileInputStream(from);
			BufferedInputStream bis = new BufferedInputStream(in);
			if (pwd == null) {
				System.out.println(base);
				System.out.println(from.length());
				int len = -1;
				while ((len = bis.read()) != -1) {
					toOut.write(len);
				}
				toOut.flush();
			} else {
				ex(zipOutputStream, pwd, in);
			}
			bis.close();
			in.close();
			zipOutputStream.closeEntry();
		}
	}

	public void decompress(File zipFile, File outFile) throws Exception {
		decompress(zipFile, outFile, null);
	}

	public void decompress(File zipFile, File outFile, String pwd) throws Exception {
		// TODO Auto-generated method stub
		long startTime = System.currentTimeMillis();
		if (outFile.exists() && outFile.isDirectory()) {
			outFile.mkdirs();
		}
		ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));// 輸入源zip路徑
		BufferedInputStream bis = new BufferedInputStream(zis);

		ZipEntry entry = null;//<span style="color:#ff0000;">用ant的時候要用<span style="font-family: Arial, Helvetica, sans-serif;">java.util.zip.</span><span style="font-family: Arial, Helvetica, sans-serif;">ZipEntry</span></span>
		while ((entry = zis.getNextEntry()) != null) {
			if (entry.isDirectory()) {
				String nameString = entry.getName();
				nameString = nameString.substring(0, nameString.length() - 1);
				File file = new File(outFile.getAbsolutePath() + File.separator + nameString);
				if (!file.exists()) {
					file.mkdirs();
				}
			} else {
				System.out.println(outFile.getAbsolutePath() + File.separator + entry.getName());
				File file = new File(outFile.getAbsolutePath() + File.separator + entry.getName());
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
				if (pwd == null) {
					int len = -1;
					while ((len = bis.read()) != -1) {
						bos.write(len);
					}
					bos.flush();
				} else {
					decompressAndPwd(zis, fos, pwd);
				}
				bos.close();
				fos.close();
				System.out.println(file.getName() + "解壓成功");
			}
		}
		bis.close();
		zis.close();
		long endTime = System.currentTimeMillis();
		System.out.println("耗費時間: " + (endTime - startTime) + " ms");
	}

	public void ex(ZipOutputStream bos, String pwd, FileInputStream bis) throws Exception {
		PBEKeySpec keySpec = new PBEKeySpec(pwd.toCharArray());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
		SecretKey passwordKey = keyFactory.generateSecret(keySpec);
		byte[] salt = new byte[8];
		Random rnd = new Random();
		rnd.nextBytes(salt);
		int iterations = 100;
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, passwordKey, parameterSpec);
		bos.write(salt);
		byte[] input = new byte[64];
		int bytesRead;
		while ((bytesRead = bis.read(input)) != -1) {
			byte[] output = cipher.update(input, 0, bytesRead);
			if (output != null) {
				bos.write(output);
			}
		}
		byte[] output = cipher.doFinal();
		if (output != null) {
			bos.write(output);
		}
		bos.flush();
	}

	public void decompressAndPwd(ZipInputStream bis, FileOutputStream bos, String pwd) throws Exception {
		PBEKeySpec keySpec = new PBEKeySpec(pwd.toCharArray());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
		SecretKey passwordKey = keyFactory.generateSecret(keySpec);
		byte[] salt = new byte[8];
		bis.read(salt);
		int iterations = 100;
		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.DECRYPT_MODE, passwordKey, parameterSpec);
		byte[] input = new byte[64];
		int bytesRead;
		while ((bytesRead = bis.read(input)) != -1) {
			byte[] output = cipher.update(input, 0, bytesRead);
			if (output != null) {
				bos.write(output);
			}
		}
		byte[] output = cipher.doFinal();
		if (output != null) {
			bos.write(output);
		}
		bos.flush();
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章