Showing posts with label ZipEntry. Show all posts
Showing posts with label ZipEntry. Show all posts

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


Tuesday, September 17, 2013

Extract zip

Sometimes, you might want to create a simple program in Java to extract zip files. If this is your case, this post can help you.  Java provides ZipFile class that can be used to read all entries in the zip file.  The ZipFile class allows you to create a zip file object by passing the path of the zip file to its constructor.  When you have the zip file object you are able to query all entries of the zip file. Each entry of the zip file is represented by a ZipEntry object. To query all entries of the zip file, you can use the entries method of the zip file object. The entries method returns an enumeration that contains all the entries.
Before extracting the content of an entry, we need to check whether the entry is a directory or file. This can be done by using the isDirectory method of the the entry object. If it is a file, then its content can read. To read the content of the file entry, you need to use the getInputStream method of the zip file object. This method return an InputStream object that has the read method to read the content of the file entry.
So far, i have talked about getting the content of the file entry. What are about directories in the zip file? Do we ignore them? The ZipFile treats a directory as one entry and also every file in the directory as one entry. When you get a file entry, its parent directory comes with it. And then you can create the parent directory that does not exist for storing the files. See the example code below.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ZipExtractor {
public static void main(String[] ars){
selectZip();
}

//allow zip file selection
public static void selectZip(){

JFileChooser chooser = new JFileChooser();
    FileNameExtensionFilter filter = new FileNameExtensionFilter("ZIP","zip");
    chooser.setFileFilter(filter);
    chooser.setMultiSelectionEnabled(false);
    int returnVal = chooser.showOpenDialog(null);
    if(returnVal == JFileChooser.APPROVE_OPTION) {
    File file=chooser.getSelectedFile();
    String path=file.toString();
    unZip(path,file.getParent());
           
            }

     
}

public static void unZip(String zippath,String storeDir){
try {
ZipFile zf=new ZipFile(zippath); //create  a zip file object
if(zf.size()>0){ //read through the zip file
Enumeration<ZipEntry> entries=(Enumeration<ZipEntry>) zf.entries();
while(entries.hasMoreElements()){
ZipEntry entry=entries.nextElement();
if(!entry.isDirectory() && !entry.getName().endsWith(File.separator)){
//start extracting the files
extractFiles(zf.getInputStream(entry),entry.getName(),storeDir);

}


}

}
zf.close();
} catch (IOException e) {

e.printStackTrace();
}
}

public static void extractFiles(InputStream is, String fname, String storeDir){

FileOutputStream fos;
File fi=new File(storeDir+File.separator+fname); //output file
File fparent=new File(fi.getParent()+File.separator);
if(!fparent.exists()) fparent.mkdirs();//create parent directories for output files

try {

fos=new FileOutputStream(fi);
int content=0;
while((content=is.read())!=-1){
fos.write(content);
}
is.close();
fos.close();
} catch (Exception e) {

e.printStackTrace();
}

}
}