zip/compress a folder full of files on android
This code should do the trick.
Note: you must add file write permissions to your app by adding the WRITE_EXTERNAL_STORAGE permission to your manifest.xml file.
/* * * Zips a file at a location and places the resulting zip file at the toLocation * Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip"); */public boolean zipFileAtPath(String sourcePath, String toLocation) { final int BUFFER = 2048; File sourceFile = new File(sourcePath); try { BufferedInputStream origin = null; FileOutputStream dest = new FileOutputStream(toLocation); ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( dest)); if (sourceFile.isDirectory()) { zipSubFolder(out, sourceFile, sourceFile.getParent().length()); } else { byte data[] = new byte[BUFFER]; FileInputStream fi = new FileInputStream(sourcePath); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } } out.close(); } catch (Exception e) { e.printStackTrace(); return false; } return true;}/* * * Zips a subfolder * */private void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException { final int BUFFER = 2048; File[] fileList = folder.listFiles(); BufferedInputStream origin = null; for (File file : fileList) { if (file.isDirectory()) { zipSubFolder(out, file, basePathLength); } else { byte data[] = new byte[BUFFER]; String unmodifiedFilePath = file.getPath(); String relativePath = unmodifiedFilePath .substring(basePathLength); FileInputStream fi = new FileInputStream(unmodifiedFilePath); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(relativePath); entry.setTime(file.lastModified()); // to keep modification time after unzipping out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } origin.close(); } }}/* * gets the last path component * * Example: getLastPathComponent("downloads/example/fileToZip"); * Result: "fileToZip" */public String getLastPathComponent(String filePath) { String[] segments = filePath.split("/"); if (segments.length == 0) return ""; String lastPathComponent = segments[segments.length - 1]; return lastPathComponent;}
this is how I do it:
private static void zipFolder(String inputFolderPath, String outZipPath) { try { FileOutputStream fos = new FileOutputStream(outZipPath); ZipOutputStream zos = new ZipOutputStream(fos); File srcFile = new File(inputFolderPath); File[] files = srcFile.listFiles(); Log.d("", "Zip directory: " + srcFile.getName()); for (int i = 0; i < files.length; i++) { Log.d("", "Adding file: " + files[i].getName()); byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(files[i]); zos.putNextEntry(new ZipEntry(files[i].getName())); int length; while ((length = fis.read(buffer)) > 0) { zos.write(buffer, 0, length); } zos.closeEntry(); fis.close(); } zos.close(); } catch (IOException ioe) { Log.e("", ioe.getMessage()); }}
I have reworked the code from HailZeon to work properly under windows. Zip Entries must be closed before new ones are started and a starting "/" at entry names like "/file.txt" makes also problems
/** * Zips a Folder to "[Folder].zip" * @param toZipFolder Folder to be zipped * @return the resulting ZipFile */public static File zipFolder(File toZipFolder) { File ZipFile = new File(toZipFolder.getParent(), format("%s.zip", toZipFolder.getName())); try { ZipOutputStream out = new ZipOutputStream(new FileOutputStream(ZipFile)); zipSubFolder(out, toZipFolder, toZipFolder.getPath().length()); out.close(); return ZipFile; } catch (Exception ex) { ex.printStackTrace(); return null; }}/** * Main zip Function * @param out Target ZipStream * @param folder Folder to be zipped * @param basePathLength Length of original Folder Path (for recursion) */private static void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException { final int BUFFER = 2048; File[] fileList = folder.listFiles(); BufferedInputStream origin = null; for (File file : fileList) { if (file.isDirectory()) { zipSubFolder(out, file, basePathLength); } else { byte data[] = new byte[BUFFER]; String unmodifiedFilePath = file.getPath(); String relativePath = unmodifiedFilePath.substring(basePathLength + 1); FileInputStream fi = new FileInputStream(unmodifiedFilePath); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(relativePath); entry.setTime(file.lastModified()); // to keep modification time after unzipping out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } origin.close(); out.closeEntry(); } }}