zip4j - Extract zip and re-zip with password in java -
i trying extract list of zip files folder , re-zipping them password. problem while re-zipping, iteration/loop not stopping. also, re-zipped files should separate zip file each rather merging contents 1 zip.
here's have tried:
import java.io.file; import java.util.arraylist; import java.util.list; import net.lingala.zip4j.core.zipfile; import net.lingala.zip4j.exception.zipexception; import net.lingala.zip4j.model.zipparameters; import net.lingala.zip4j.util.zip4jconstants; public class addfileswithaesencryption2 { public addfileswithaesencryption2() { try { //extract zip files folders try { string zipsourcepath = "e:/eziptest/"; string extractto = "d:/dziptest/"; string files1; file folder1 = new file(zipsourcepath); file[] listoffiles1 = folder1.listfiles(); (int = 0; < listoffiles1.length; i++) { if (listoffiles1[i].isfile()) { files1 = listoffiles1[i].getname(); string zipfiles = "e:/eziptest/" + files1; try { zipfile zipfile = new zipfile(zipfiles); list fileheaderlist = zipfile.getfileheaders(); zipfile.extractall(extractto); } catch (zipexception e) { e.printstacktrace(); } } } //get list of folders string directorynames; string extracteddirectories1 = "d:/dziptest/"; file folder2 = new file(extracteddirectories1); file[] listoffiles2 = folder2.listfiles(); (int = 0; < listoffiles2.length; i++) { if (listoffiles2[i].isdirectory()) { directorynames = listoffiles2[i].getname(); string listofdirectories = "d:/dziptest/" + directorynames; //get list of files string extracteddirectories = listofdirectories; file folder3 = new file(extracteddirectories); file[] listoffiles3 = folder3.listfiles(); (int j = 0; j < listoffiles3.length; j++) { file file = listoffiles3[j]; if (file.isfile()) { string filenames = file.getname(); system.out.println(listofdirectories + filenames); //compress , zip files zipfile zipfile = new zipfile("d:/" + listoffiles2[i].getname() + ".zip"); arraylist filestoadd = new arraylist(); filestoadd.add(new file(listofdirectories + filenames)); zipparameters parameters = new zipparameters(); parameters.setcompressionmethod(zip4jconstants.comp_deflate); // set compression method deflate compression parameters.setcompressionlevel(zip4jconstants.deflate_level_normal); parameters.setencryptfiles(true); parameters.setencryptionmethod(zip4jconstants.enc_method_aes); parameters.setaeskeystrength(zip4jconstants.aes_strength_256); parameters.setpassword("test"); zipfile.addfiles(filestoadd, parameters); } } } } } catch (zipexception e) { e.printstacktrace(); } } catch (exception e) { e.printstacktrace(); } } public static void main(string[] args) { new addfileswithaesencryption2(); } }
refactoring
refactoring code understand does. reveal problem , identify fix. here's how goes. note not complete tutorial, hope point.
first, extract nice method unzipping. mark inside first for
loop, right click , choose refactor / extract method...
. name unzipfile
. note have nice small, potentially reusable , potentially testable (junit) method.
next, mark zipparameters parameters
parameters.setpassword("test");
right click, refactor / extract method...
. name getencryptionparameters
. note how 7 lines of code have been removed long method , readability improved.
right click on parameters
, choose refactor / inline ...
. note how temporary variable disappears.
see bug
if have followed closely, there piece of code this:
//compress , zip files zipfile zipfile = new zipfile("d:/" + listoffiles2[i].getname() + ".zip"); arraylist filestoadd = new arraylist(); filestoadd.add(new file(listofdirectories + filenames)); zipfile.addfiles(filestoadd, getencryptionparameters());
see does? creates new zip file, adds one file filestoadd
, that's it. why? says filenames
. how can 1 file only?
looking @
string filenames = file.getname();
that's 1 file, variable name wrong.
right click filenames
, choose refactor/rename...
. enter filename
. note how variable name in program matches is. heavily improves readability of code.
simplify
now know you're adding 1 file, use addfile()
instead of addfiles()
. you're getting rid of arraylist
:
//compress , zip files zipfile zipfile = new zipfile("d:/" + listoffiles2[i].getname() + ".zip"); file filetoadd = new file(listofdirectories + filename); zipfile.addfile(filetoadd, getencryptionparameters());
fix bug
as spotted before, new zipfile(...)
created inside loop , 1 file added it. move line out of loop pressing alt+up.
continue refactoring
a part of problem fixed (i haven't tried, actually), code still not error-free. let's go on:
mark file[] listoffiles3
end of for
loop follows. right click, refactor/extract method...
, name rezip
. big method becomes smaller again.
right click on extracteddirectories
, refactor / inline ...
. got rid of unnecessary temporary variable.
see something? code should this:
//get list of files file folder3 = new file(listofdirectories); rezip(listoffiles2, i, listofdirectories, folder3);
note how folder3
, listofdirectories
same. let's rid of it. move line file folder3 = new file(listofdirectories);
method, behind private void rezip(...){
, remove parameter file folder3
both, method call , method declaration of rezip()
.
the loop using rezip()
looks this:
for (int = 0; < listoffiles2.length; i++) { if (listoffiles2[i].isdirectory()) { directorynames = listoffiles2[i].getname(); string listofdirectories = "d:/dziptest/" + directorynames; rezip(listoffiles2, i, listofdirectories); } }
you might spot directorynames
one, not many. right click, refactor/rename...
. enter subdirectory
.
right click subdirectory
, refactor / inline ...
. read error message. right click references / workspace
. check results , find out variable used within for
loop. delete declaration outside , declare @ first use. refactor / inline ...
operation.
your code looks this:
for (int = 0; < listoffiles2.length; i++) { if (listoffiles2[i].isdirectory()) { string listofdirectories = "d:/dziptest/" + listoffiles2[i].getname(); rezip(listoffiles2, i, listofdirectories); } }
again, there's variable name indicating list or array, that's not true. refactor / rename...
, name directorytozip
.
inline following variables in order: extracteddirectories1
, folder2
, zipsourcepath
, folder1
.
rename in order listoffiles1
zipfiles
, listoffiles2
extracteddirectories
.
remove files1
since never used.
the final bug
the method short , readable enough understand completely. following make sense?
string extractto = "d:/dziptest/"; file[] zipfiles = new file("e:/eziptest/").listfiles(); (int = 0; < zipfiles.length; i++) { unzipfile(extractto, zipfiles, i); } file[] extracteddirectories = new file("d:/dziptest/").listfiles(); (int = 0; < extracteddirectories.length; i++) { if (extracteddirectories[i].isdirectory()) { string directorytozip = "d:/dziptest/" + extracteddirectories[i].getname(); rezip(extracteddirectories, i, directorytozip); } }
no doesn't.
- you don't want extract archives first 1 one
- you don't want zip subdirectories, want zip in
extractto
directory
fixing final bug
the signature of unzipfile()
not right. if unzips 1 file name suggests, why access files then?
replace unzipfile(extractto, zipfiles, i);
unzipfile(extractto, zipfiles[i]);
. breaks code. eclipse mark red. fix changing parameters from
private void unzipfile(string extractto, file[] listoffiles1, int i)
to
private void unzipfile(string extractto, file listoffiles1)
inside unzip
, replace listoffiles1[i]
listoffiles1
. refactor/rename...
sourcezipfile
.
similar rezip
method: should directory zip , target file name only. therefore change
rezip(extracteddirectories, i, directorytozip);
to
rezip(extracteddirectories[i], directorytozip);
then adapt method
private void rezip(file[] listoffiles2, int i, string listofdirectories) throws zipexception
to
private void rezip(file listoffiles2, string listofdirectories) throws zipexception
then change listoffiles2[i]
listoffiles2
. rename targetfile
.
now have nice unzipfile()
method , rezip()
method. let's combine in cool way:
string extractto = "d:/dziptest/"; file[] zipfiles = new file("e:/eziptest/").listfiles(); (int = 0; < zipfiles.length; i++) { unzipfile(extractto, zipfiles[i]); rezip(zipfiles[i], extractto); // todo: delete extracted files here }
awesome, ain't it?
notes
maybe you've seen how effort understand code , provide fix. actually, effort stack overflow. next time ask question, please try provide code @ minumum readable code now.
the code still not clean should be. spend more time on it. when think it's superb, post on https://codereview.stackexchange.com/ more instructions.
Comments
Post a Comment