package com.AB.ABZipUnzip;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
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.util.Enumeration;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* Object that does zip en unzip files on the device
*/
@ShortName("ABZipUnzip")
@Permissions(values={"android.permission.WRITE_EXTERNAL_STORAGE"})
@Version(1.0f)
@Author("Alain Bailleul")
public class ABZipUnzip {
private static CopyOnWriteArrayList<ABZipContent> _theZip=null;
private static String SOURCE_FOLDER = "";
/**
* zip a folder with all its files and subdirectories
*
* Example:<code>
* myzip.ABZipDirectory(sdRoot & "start", sdRoot & "myZip.zip")
* </code>
*/
public boolean ABZipDirectory(String sourceDir, String zipFile) {
//String sourceDir = "C:/examples";
//String zipFile = "C:/FileIO/zipdemo.zip";
SOURCE_FOLDER = sourceDir;
try {
boolean wasOK=false;
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File fileSource = new File(sourceDir);
wasOK = addDirectory(zout, fileSource, true);
zout.close();
System.out.println("Zip file has been created!");
return wasOK;
}
catch(IOException ioe) {
System.out.println("IOException :" + ioe);
return false;
}
}
/**
* Zip a single file
*
* sourcePath must end with "/"
*
* Example:<code>
* myzip.ABZipFile(sdRoot & "start/" , "test4.txt", sdRoot & "myZipOneFile.zip")
* </code>
*/
public boolean ABZipfile(String sourcePath, String sourceFile, String zipFile) {
//String zipFile = "C:/FileIO/zipdemo.zip";
//String sourceFile = "C:/FileIO/sourcefile.doc
try
{
byte[] buffer = new byte[1024];
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
FileInputStream fin = new FileInputStream(sourcePath + sourceFile);
zout.putNextEntry(new ZipEntry(sourceFile));
int length;
while((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
zout.close();
System.out.println("Zip file has been created!");
return true;
}
catch(IOException ioe) {
System.out.println("IOException :" + ioe);
return false;
}
}
/**
* Unzip a zip file
*
* Example:<code>
* myZip.ABUnzip(sdRoot & "myZip.zip", sdRoot & "target")
* </code>
*/
public boolean ABUnzip(String zipFile, String targetPath) {
//String strZipFile = args[0];
if(zipFile == null || zipFile.equals("")) {
System.out.println("Invalid source file");
return false;
}
System.out.println("Zip file extracted!");
return unzip(zipFile, targetPath);
}
private static boolean unzip(String zipFile, String targetPath) {
try {
File fSourceZip = new File(zipFile);
//String zipPath = zipFile.substring(0, zipFile.length()-4);
//File temp = new File(zipPath);
//temp.mkdir();
File temp = new File(targetPath);
temp.mkdir();
System.out.println(targetPath + " created");
ZipFile zFile = new ZipFile(fSourceZip);
Enumeration e = zFile.entries();
while(e.hasMoreElements()) {
ZipEntry entry = (ZipEntry)e.nextElement();
File destinationFilePath = new File(targetPath,entry.getName());
destinationFilePath.getParentFile().mkdirs();
if(entry.isDirectory()) {
continue;
}
else {
System.out.println("Extracting " + destinationFilePath);
BufferedInputStream bis = new BufferedInputStream(zFile.getInputStream(entry));
int b;
byte buffer[] = new byte[1024];
FileOutputStream fos = new FileOutputStream(destinationFilePath);
BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
while ((b = bis.read(buffer, 0, 1024)) != -1) {
bos.write(buffer, 0, b);
}
bos.flush();
bos.close();
bis.close();
}
}
}
catch(IOException ioe) {
System.out.println("IOError :" + ioe);
return false;
}
return true;
}
/**
* List the contents of a zip file
*
* Example:<code>
* Dim myZipFile as ABZipContent
*
* listview1.Clear
* counter = myzip.ABListZip(sdRoot & "myZipOneFile.zip")
* For a = 0 To counter - 1
* myZipFile = myZip.ABGetListItem(a)
* listview1.AddTwoLines(myZipfile.Name, "Size: " & MyZipfile.Size & " bytes Compressed Size: " & myzipFile.CompressedSize & " bytes")
* Next
* </code>
*/
public int ABListZip(String zipFile) {
_theZip = new CopyOnWriteArrayList<ABZipContent>();
ABZipContent _tmpABC=null;
int counter=0;
try {
File fSourceZip = new File(zipFile);
ZipFile zFile = new ZipFile(fSourceZip);
Enumeration e = zFile.entries();
while(e.hasMoreElements()) {
ZipEntry entry = (ZipEntry)e.nextElement();
_tmpABC = new ABZipContent();
_tmpABC._Name = entry.getName();
_tmpABC._CompressedSize = entry.getCompressedSize();
_tmpABC._Size = entry.getSize();
_tmpABC._IsDirectory = entry.isDirectory();
_tmpABC._Type = 1; //new
_theZip.add(_tmpABC);
counter++;
}
}
catch(IOException ioe) {
System.out.println("IOError :" + ioe);
return -1;
}
return counter;
}
/**
* Get one if the items in the zipfile to get more information. Fill this list first by calling ABListZip()
*/
public ABZipContent ABGetListItem(int index) {
return _theZip.get(index);
}
private static String generateZipEntry(String file){
return file.substring(SOURCE_FOLDER.length()+1, file.length());
}
private static boolean addDirectory(ZipOutputStream zout, File fileSource, boolean isRoot) {
boolean wasOK=false;
File[] files = fileSource.listFiles();
System.out.println("Adding directory " + fileSource.getName());
for(int i=0; i < files.length; i++) {
if(files[i].isDirectory()) {
wasOK = addDirectory(zout, files[i], false);
if (wasOK==false) {
return false;
}
continue;
}
try {
System.out.println("Adding file " + files[i].getAbsolutePath());
byte[] buffer = new byte[1024];
FileInputStream fin = new FileInputStream(files[i].getAbsoluteFile());
if (isRoot==true) {
zout.putNextEntry(new ZipEntry(generateZipEntry(files[i].getAbsoluteFile().toString())));
} else {
zout.putNextEntry(new ZipEntry(generateZipEntry(files[i].getAbsoluteFile().toString())));
}
int length;
while((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
catch(IOException ioe) {
System.out.println("IOException :" + ioe);
return false;
}
}
return true;
}
/**
* An object that the contains information about an entry in the zip file
*/
@ShortName("ABZipContent")
public static class ABZipContent {
String _Name = "";
Long _CompressedSize = (long) 0;
Long _Size = (long) 0;
boolean _IsDirectory = false;
int _Type = 0;
/**
* Returns the full path and name of the entry
*/
public String getName() {
return _Name;
}
/**
* Returns the compressed size of the entry
*/
public Long getCompressedSize() {
return _CompressedSize;
}
/**
* Returns the uncompressed size of the entry
*/
public Long getSize() {
return _Size;
}
}
}