protected void unpackComponents() throws IOException, FileNotFoundException { File applicationPackage = new File(getApplication().getPackageResourcePath()); File componentsDir = new File(sGREDir, "components"); if (componentsDir.lastModified() == applicationPackage.lastModified()) return; componentsDir.mkdir(); componentsDir.setLastModified(applicationPackage.lastModified()); GeckoAppShell.killAnyZombies(); ZipFile zip = new ZipFile(applicationPackage); byte[] buf = new byte[32768]; try { if (unpackFile(zip, buf, null, "removed-files")) removeFiles(); } catch (Exception ex) { // This file may not be there, so just log any errors and move on Log.w(LOG_FILE_NAME, "error removing files", ex); } // copy any .xpi file into an extensions/ directory Enumeration<? extends ZipEntry> zipEntries = zip.entries(); while (zipEntries.hasMoreElements()) { ZipEntry entry = zipEntries.nextElement(); if (entry.getName().startsWith("extensions/") && entry.getName().endsWith(".xpi")) { Log.i("GeckoAppJava", "installing extension : " + entry.getName()); unpackFile(zip, buf, entry, entry.getName()); } } }
private boolean unpackFile(ZipFile zip, byte[] buf, ZipEntry fileEntry, String name) throws IOException, FileNotFoundException { if (fileEntry == null) fileEntry = zip.getEntry(name); if (fileEntry == null) throw new FileNotFoundException("Can't find " + name + " in " + zip.getName()); File outFile = new File(sGREDir, name); if (outFile.lastModified() == fileEntry.getTime() && outFile.length() == fileEntry.getSize()) return false; File dir = outFile.getParentFile(); if (!dir.exists()) dir.mkdirs(); InputStream fileStream; fileStream = zip.getInputStream(fileEntry); OutputStream outStream = new FileOutputStream(outFile); while (fileStream.available() > 0) { int read = fileStream.read(buf, 0, buf.length); outStream.write(buf, 0, read); } fileStream.close(); outStream.close(); outFile.setLastModified(fileEntry.getTime()); return true; }
/** * Zips byte array. * * @param input Input bytes. * @param initBufSize Initial buffer size. * @return Zipped byte array. * @throws IOException If failed. */ public static byte[] zipBytes(byte[] input, int initBufSize) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(initBufSize); try (ZipOutputStream zos = new ZipOutputStream(bos)) { ZipEntry entry = new ZipEntry(""); try { entry.setSize(input.length); zos.putNextEntry(entry); zos.write(input); } finally { zos.closeEntry(); } } return bos.toByteArray(); }