If you are using a version earlier than Java 7, the best way to do this is to unzip the files inside the .zip and play along with the new files in a new .zip.
Based in Soen’s reply.
private static void addFilesToZip(File source, File[] files, String path){
try{
File tmpZip = File.createTempFile(source.getName(), null);
tmpZip.delete();
if(!source.renameTo(tmpZip)){
throw new Exception("Não foi possível criar o arquivo temporário (" + source.getName() + ")");
}
byte[] buffer = new byte[TAMANHO_BUFFER];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
for(int i = 0; i < files.length; i++){
InputStream in = new FileInputStream(files[i]);
out.putNextEntry(new ZipEntry(path + files[i].getName()));
for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
out.write(buffer, 0, read);
}
out.closeEntry();
in.close();
}
for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
if(!zipEntryMatch(ze.getName(), files, path)){
out.putNextEntry(ze);
for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
out.write(buffer, 0, read);
}
out.closeEntry();
}
}
out.close();
tmpZip.delete();
}catch(Exception e){
e.printStackTrace();
}
}
private static boolean zipEntryMatch(String zeName, File[] files, String path){
for(int i = 0; i < files.length; i++){
if((path + files[i].getName()).equals(zeName)){
return true;
}
}
return false;
}
This second method checks if there is no file with the same name inside the Zip. Obviously this needs to be improved, but it is already a good starting point.
If you are using Java 7. You can use the library java. and do so (Example taken from here)
private static void addNoZipExistente(String arqZip, String arqInserir, String nomeArquivoNoZip){
Map<String, String> env = new HashMap<>();
env.put("create", "true");
URI uri = URI.create("jar:" + "file:/" + arqZip.replace("\\", "/"));
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env))
{
Path arquivoParaInserir = Paths.get(arqInserir);
Path localNoZip = zipfs.getPath(nomeArquivoNoZip);
Files.copy(arquivoParaInserir, localNoZip, StandardCopyOption.REPLACE_EXISTING );
}catch(IOException ioex){
//Tratar o erro
}
}
Other than that, I would also change the way you receive the parameters in the method compactarParaZip()
, so that it can receive multiple parameters. Maybe you only need two, but this makes the method more dynamic.
public static void compactarParaZip(String arqSaida, String... entradas) throws IOException {
FileOutputStream destino;
ZipOutputStream saida;
try {
destino = new FileOutputStream(new File(arqSaida));
saida = new ZipOutputStream(new BufferedOutputStream(destino));
for(String arq : entradas){
add(arq, saida);
}
saida.close();
} catch (IOException e) {
throw new IOException(e.getMessage());
}
}
An example of how to use it would be
compactarParaZip("novoArquivo.zip", "arq1.txt", "arq2.txt", "arq3.txt");
// posso colocar quantos parâmetros quiser
The two answers would solve the problem, but I chose the @jbueno because it is more complete and explanatory.
– DiegoAugusto