Sunday, September 29, 2013

Create zip file

In the previous post, you learned to create a simple program to extract an existing zip file. Sometimes, you might want to implement file zipping in your programs. So it is worth to learn how to write Java code to create a zip file or many zip files.

In contrasting to zip file extraction, you need to use the ZipOutputStream class to write the contents of the source files or directories to the output file. The ZipEntry class is used to create a zip entry object. This object can be file or directory. The putEntry method of the ZipOutputStream class is used to add the zip entry to the output zip file. Its write method is used to write the content of a source file object to the output zip file.

The below example program allows the user to add many files or directories to the JList component. When the OK button is clicked, all paths of the source files or directories are processed to create zip files. The output zip files are placed in your current working project folder.
The zipFile method is the main path of the program. The sources to be zipped can be file or directory so that they are processed separately. We create additioal two methods, compressFile and compressDir. If the source is a file object, the compressFile method is invoked to compress the file. Otherwise, the compressDir is invoked to compress the contents of the directory. The contents of the directory can be files or directories so the compressFile and compressDir methods are invoked recursively until all files and directories are written to the output zip file.



import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

class ZipUI extends JFrame implements ActionListener{
DefaultListModel<String> listModel;
JList<String> listPaths;
JTextField textPath;
JLabel lblwait;

ZipUI(String title){
Container cont=getContentPane();
cont.setLayout(new BorderLayout());
setTitle(title);
setPreferredSize(new Dimension(600,300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lbl=new JLabel("Path:");
textPath=new JTextField(30);
JButton btadd=new JButton("Add");
btadd.addActionListener(this);
JButton btremove=new JButton("Remove");
btremove.addActionListener(this);
JPanel panelnorth=new JPanel();
panelnorth.add(lbl);
panelnorth.add(textPath);
panelnorth.add(btadd);
panelnorth.add(btremove);
listModel=new DefaultListModel<String>();
listPaths=new JList<String>(listModel);
listPaths.setVisibleRowCount(10);
listPaths.setFixedCellWidth(200);
JScrollPane pane=new JScrollPane(listPaths);
JButton btok=new JButton("OK");
lblwait=new JLabel();
JPanel panelsouth=new JPanel();
panelsouth.add(btok);
panelsouth.add(lblwait);
btok.addActionListener(this);
cont.add(panelnorth, BorderLayout.NORTH);
cont.add(pane, BorderLayout.CENTER);
cont.add(panelsouth, BorderLayout.SOUTH);
pack();
setVisible(true);
}

public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Add")){
if(!textPath.getText().equals("")){
listModel.addElement(textPath.getText());
textPath.setText("");
}
else
JOptionPane.showMessageDialog(null, "Please enter the file or directory path", "Add path",JOptionPane.INFORMATION_MESSAGE);


}
else if(e.getActionCommand().equals("Remove")){
if(listModel.getSize()>0){
int selIndex=listPaths.getSelectedIndex();
if(selIndex>=0)
listModel.removeElementAt(selIndex);
else
JOptionPane.showMessageDialog(null, "No selected item", "Delete error",JOptionPane.ERROR_MESSAGE);
}
else
JOptionPane.showMessageDialog(null, "No item in the list", "Delete error",JOptionPane.ERROR_MESSAGE);
}
else if(e.getActionCommand().equals("OK")){
if(listModel.getSize()>0){
Thread t=new Thread(){
public void run(){
lblwait.setText("Please wait...");

for(int i=0;i<listModel.size();i++){
zipFile(listModel.get(i));
}
//dispose();
lblwait.setText("Complete! check the file(s) in /zip");
}
};
t.start();
}
else
JOptionPane.showMessageDialog(null, "No such file or directory", "Error",JOptionPane.ERROR_MESSAGE);
}
}

//zip file or directory
public void zipFile(String src){
File f=new File(src);
File foutdir=new File(System.getProperty("user.dir")+"/zip");
if(!foutdir.exists()) foutdir.mkdir();
ZipOutputStream zos=null;
try{
zos=new ZipOutputStream(new FileOutputStream(foutdir.getPath()+"/zip"+System.currentTimeMillis()+".zip"));
if(f.exists()){
String fname=getName(f.getPath());
if(f.isFile()){
compressFile(f.getPath(),fname,zos);
}
else{ //source is a directory
File[] files=f.listFiles();
for(File sf:files){
compressDir(sf.getPath(),fname,zos);
}
}


}
else{
System.out.println("Soure not found!");
}
zos.close();

}catch(Exception e){e.printStackTrace();}

}
//get the name of source file or directory
public String getName(String srcpath){

String name="";
if(srcpath.endsWith(File.separator)){
name=srcpath.substring(0,srcpath.length()-1);
name=name.substring(name.lastIndexOf(File.separator)+1);
}
else
name=srcpath.substring(srcpath.lastIndexOf(File.separator)+1);

return name;
}
//zip the directory and its contents
public void compressDir(String srcpath, String dirname, ZipOutputStream zos){
File fsrcdir=new File(srcpath);
String curDirName=getName(srcpath);
if(fsrcdir.isDirectory()){
try {
//add the blank folder to the zip file
//its previous path is maintained
curDirName=dirname+File.separator+curDirName;
zos.putNextEntry(new ZipEntry(curDirName+File.separator));
zos.closeEntry();
//read the contents of the directory and place them in the zip file
File[] files=fsrcdir.listFiles();
for(File f:files){
if(f.isDirectory()){ //process one directory download
compressDir(f.getPath(),curDirName,zos);
}
else{//process the file
compressFile(f.getPath(),curDirName,zos);
}
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
compressFile(srcpath,dirname,zos);
}
}
//zip the file
public void compressFile(String srcfile, String dirname,ZipOutputStream zos){

String rpath=getName(srcfile);
//The rpath is a directory name that the file will be stored in
//It is the immediate parent directory of the file
try {
//placing one file entry
zos.putNextEntry(new ZipEntry(dirname+File.separator+rpath));
//create FileInputStream object to read content of the file
FileInputStream fis=new FileInputStream(srcfile);
int content=0;
while((content=fis.read())!=-1){
zos.write(content);
}
zos.closeEntry(); //closing one file entry
fis.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}


public class CreateZipFile {
public static void main(String[] args){
new ZipUI("Zipper");
}


}


add file and directories to the zip file program


No comments:

Post a Comment