DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Adding Files To An Existing Jar File

02.07.2007
| 40263 views |
  • submit to reddit
        Adds files to an existing Zip file. <br />
Overwrites zip entries with the same name as one of the new files. 

The function renames the existing zip file to a temporary file and then adds all entries in the existing zip along with the new files, excluding the zip entries that have the same name as one of the new files. <br />

Note: I'm not sure I used the best way to get a temp file. A snippet for that is welcome :)

	
	public static void addFilesToExistingZip(File zipFile,
			 File[] files) throws IOException {
                // get a temp file
		File tempFile = File.createTempFile(zipFile.getName(), null);
                // delete it, otherwise you cannot rename your existing zip to it.
		tempFile.delete();

		boolean renameOk=zipFile.renameTo(tempFile);
		if (!renameOk)
		{
			throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
		}
		byte[] buf = new byte[1024];
		
		ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
		
		ZipEntry entry = zin.getNextEntry();
		while (entry != null) {
			String name = entry.getName();
			boolean notInFiles = true;
			for (File f : files) {
				if (f.getName().equals(name)) {
					notInFiles = false;
					break;
				}
			}
			if (notInFiles) {
				// Add ZIP entry to output stream.
				out.putNextEntry(new ZipEntry(name));
				// Transfer bytes from the ZIP file to the output file
				int len;
				while ((len = zin.read(buf)) > 0) {
					out.write(buf, 0, len);
				}
			}
			entry = zin.getNextEntry();
		}
		// Close the streams		
		zin.close();
		// Compress the files
		for (int i = 0; i < files.length; i++) {
			InputStream in = new FileInputStream(files[i]);
			// Add ZIP entry to output stream.
			out.putNextEntry(new ZipEntry(files[i].getName()));
			// Transfer bytes from the file to the ZIP file
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			// Complete the entry
			out.closeEntry();
			in.close();
		}
		// Complete the ZIP file
		out.close();
		tempFile.delete();
	}
    

Comments

Snippets Manager replied on Tue, 2008/02/19 - 6:18am

Worked great for me. Well done, thanks! Daim, unfortunately ZipOutputStream throws an IOException ("duplicate entry") if you try to overwrite a ZipEntry in it[1]. A workaround is suggested in [2], but it basically does the same as the code above. [1] http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=313c4381e5a47920fbef7c4de1a16?bug_id=4129445 [2] http://www.daniweb.com/forums/thread109142.html

Snippets Manager replied on Sat, 2008/02/16 - 8:47am

Wouldn't it be much faster just to add all original zip files to the outputstream and then add all new files by overwriting the old ones instead of comparing each new file to all original files?

Mark Macumber replied on Thu, 2007/08/16 - 10:20pm

This is a nice snippet. It worked very well, thanks!