I am trying to create directories in a .zip file but only one directory is being created in the .zip. I'm not sure why only the first directory gets created. zip() method gets called everytime theres a directory.
Method to list files:
private Set<String> listFiles(String path){
File f = new File(path);
Set<String> files = new HashSet<>();
for(File file : Objects.requireNonNull(f.listFiles())){
files.add(file.getPath());
}
return files;
}
Method to zip:
private void zip(Set<String> path){
try {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream;
ZipOutputStream zipOutputStream;
File f;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("/sdcard/Android/data/com.kpwnapps.pmmpplugins/files/PocketMine-MP/test.zip"));
zipOutputStream= new ZipOutputStream(bufferedOutputStream, StandardCharsets.UTF_8);
for (String file : path){
f = new File(file);
if (f.isDirectory()){
zipOutputStream.putNextEntry(new ZipEntry(f.getName() + "/"));
zip(listFiles(f.getPath()));
}else {
bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
zipOutputStream.putNextEntry(new ZipEntry(f.getName()));
IOUtils.copy(bufferedInputStream, zipOutputStream);
zipOutputStream.closeEntry();
}
*/
}
if (bufferedInputStream != null){
bufferedInputStream.close();
}
zipOutputStream.flush();
zipOutputStream.close();
}
}catch (Exception ignored){
}
}
I'm mildly surprised that this even works.
When your
zip()
method calls itself recursively it creates a newFileOutputStream
with the same filename as the previous call. That means that your recursive calls write on top of each other instead of appending to a single zip file.You should open the FileOutputStream / ZipOutputStream only once and then use it for zipping all files and directories.
That means rewriting some of your code so that at the first level of zipping you create the
zipOutputStream
and then call an internal methodzip(path, zipOutputStream)
. The recursive calls also must call thiszip(path, zipOutputStream)
method.This will look something like