//这个小软件有两个类,实现了500MB文件压缩,太大的话容易出问题,还没解决
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.xml.parsers.FactoryConfigurationError;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JButton;
import javax.swing.JFileChooser;
/**
* 主界面类
* @author yan
*
*/
public class ZipUI extends JFrame implements ActionListener{
public JPanel contentPane;
public static JTextField textField;
public static JTextField textField_1;
public static JButton bopen;
public static JButton bys;
public static JButton bqx ;
public static JButton bjy;
private APIzip az;
private String pathopen;
private JLabel lblNewLabel_3;
private JTextPane area;
public static void main(String[] args) {
ZipUI frame = new ZipUI();
frame.setVisible(true);
}
/**
* 创建界面
*/
public ZipUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(400, 200, 450, 320);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblNewLabel = new JLabel("需要压缩或解压文件..");
lblNewLabel.setBounds(54, 10, 129, 29);
contentPane.add(lblNewLabel);
textField = new JTextField();
textField.setBounds(54, 49, 252, 21);
contentPane.add(textField);
textField.setColumns(10);
bopen = new JButton("打开文件");
bopen.setBounds(316, 49, 93, 23);
bopen.addActionListener(this);
contentPane.add(bopen);
bys = new JButton("压缩文件");
bys.setBounds(54,90, 93, 23);
bys.addActionListener(this);
contentPane.add(bys);
bjy = new JButton("解压文件");
bjy.setBounds(170, 90, 93, 23);
bjy.addActionListener(this);
contentPane.add(bjy);
bqx = new JButton(" 取 消");
bqx.setBounds(290, 90, 120, 23);
bqx.addActionListener(this);
contentPane.add(bqx);
JLabel lblNewLabel_2 = new JLabel("详细信息....");
lblNewLabel_2.setBounds(54,120, 129, 30);
contentPane.add(lblNewLabel_2);
area = new JTextPane();
JScrollPane jsp = new JScrollPane(area);
jsp.setBounds(54,150,350,100);
contentPane.add(jsp);
lblNewLabel_3 = new JLabel();
lblNewLabel_3.setBounds(290,245, 200,40);
contentPane.add(lblNewLabel_3);
az=new APIzip(area);
}
public void actionPerformed(ActionEvent e) {
JFileChooser jfc=new JFileChooser();
//设置要显示的文件类型(括号里面的值)
jfc.setFileSelectionMode(jfc.FILES_AND_DIRECTORIES);//设置文件
if (e.getSource() ==bopen) {
jfc.showOpenDialog(null);
pathopen=jfc.getSelectedFile().toString();//本来得到一个文件类型,但是需要在text上面显示
textField.setText(pathopen);
}
//压缩文件
if(e.getSource()==bys){
if(pathopen.endsWith(".zip")){
JOptionPane.showMessageDialog(null, "已经是压缩文件,不能重复压缩!");
}else{
pathopen =textField.getText();
double t1=System.currentTimeMillis();
az.CreateZip(pathopen);
lblNewLabel_3.setText("压缩耗费时间... "+(System.currentTimeMillis()-t1)/1000);
}
}
//解压文件
if(e.getSource()==bjy){
if(pathopen.endsWith(".zip")){
pathopen =textField.getText();
double t1=System.currentTimeMillis();
az.jieya(pathopen);
lblNewLabel_3.setText("解压耗费时间... "+(System.currentTimeMillis()-t1)/1000);
}else{
JOptionPane.showMessageDialog(null, "不是压缩文件,无法解压!");
}
}
if(e.getSource()==bqx){
//结束(取消)
System.exit(0);
}
}
}
//第二个类,实现解压和压缩,用到了递归遍历文件
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.swing.JLabel;
import javax.swing.JTextPane;
/**
* 实现了压缩和解压方法
* @author yan
*
*/
public class APIzip {
private JTextPane area;
/**
*
* @param area 由界面的JTextPane 将文件详细信息写入
*/
public APIzip(JTextPane area) {
this.area=area;
}
/**
* 压缩方法
* @param path1 需要压缩的文件的名称
* 1.利用递归得到子文件
* 2.创建ZipOutputStream
* 3.遍历得到每一个文件的输入流
* 4.开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
* 5.读与写
*/
public void CreateZip(String path1){
try {
String path2=path1+".zip";//压缩完后的文件路径直接在后面加.zip
List<File> list=getFiles(path1); //1.利用递归得到子文件
ZipOutputStream out =new ZipOutputStream(new FileOutputStream(new File(path2)));//2.创建ZipOutputStream
for(File f: list){
InputStream in=new FileInputStream(f);//3.遍历得到每一个文件的输入流,读取数据
String name=getRelName(path1,f);//
// 4.开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处
ZipEntry en=new ZipEntry(new File(path1).getName()+"/"+name);
en.setSize(f.length());
/***
* 开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。
* 如果仍处于活动状态,则关闭当前条目。如果没有为条目指定压缩方法,
* 则使用默认的压缩方法;如果没有为条目设置修改时间,则使用当前时间。
*/
out.putNextEntry(en);
int size=100;
long length=f.length();
//粗略计算文件大小,来设置数组大小,利于快速传送
if(length>10000000){
size=1000000;
}else if(length>1000000){
size=100000;
}else if(length>100000){
size=10000;
}else if(length>10000){
size=1000;
}
//5.边读与边写
int len=0;
byte[] b=new byte[size];
while((len=in.read(b))!=-1){
out.write(b,0,size);
}
in.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件的相对路径
* @param path1 需要压缩的文件路径
* @param f 需要压缩的文件子文件
* @return 字符串(路径)
*/
private String getRelName(String path1, File f) {
String a=f.getAbsolutePath().replace(path1+"\\","");
a=a.replace("\\", "/");
System.out.println(path1+"---"+a);
String text=area.getText();
area.setText(text+path1+"---"+a+"\r\n");
if(text.length()>1000){
area.setText(a+"\r\n");
}
return a;
}
/**利用递归得到子文件
* 获取路径下所有文件,包括文件夹下的
* @param path1
* @return 文件夹里面的子文件
*/
private List<File> getFiles(String sou) {
List<File> list=new ArrayList<File>();
File f=new File(sou);
File files[]=f.listFiles();
for(File file: files){
if(file.isFile()){
list.add(file);
}else{
list.addAll(getFiles(file.getPath()));
}
}
return list;
}
/**
* 解压
* @param path2 需要解压的文件路径
*
*/
public void jieya(String path2){
try {
//设置文件名称
int i=path2.indexOf(":");
String s=path2.substring(0,i);
String path3=s+":\\";
//创建压缩文件
ZipFile zf=new ZipFile(new File(path2));
InputStream is;
Enumeration en=zf.entries();//返回 ZIP 文件条目的枚举。
while(en.hasMoreElements()){
ZipEntry zn=(ZipEntry) en.nextElement();//遍历ZIP文件条目
if(!zn.isDirectory()){
is=zf.getInputStream(zn);//得到输入流
File f=new File (path3+zn.getName());
// 返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
File file=f.getParentFile();
// 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
file.mkdirs();
FileOutputStream fos=new FileOutputStream(path3+zn.getName());
int len;
byte b[] =new byte[1024];
while((len=is.read(b))!=-1){
fos.write(b,0,len);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//希望有更好的办法的大神来指教!