Hi, I know my solution may be not the most efficient but it works!
Is there any bug that makes all requirements fail ? Something like System.exit() ?
Any help would be appreciated!
package com.codegym.task.task31.task3105;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/*
Adding a file to an archive
*/
public class Solution {
public static void main(String[] args) throws IOException {
//My strategy:
//1 - Create specialDir in root of archive
//2 - Copy file-to-add-to-archive to specialDir/new
//3 - Unzip all files from archive to specialDir directory
//4 - Delete old archive
//5 - Walk file tree specialDir and zip it all to archive with the same name as old one
// locally works great as long as there are no directories in archive file but validator is making me nervous!!!
//1 Create specialDir in root of archive
String specialDir = args[1].substring(0,args[1].lastIndexOf("\\"))+"\\specialDir";
File theDir = new File(specialDir);
if (!theDir.exists()) theDir.mkdirs();
//1 is done!
//2 Copy file-to-add-to-archive to specialDir/new
File theDirNew = new File(specialDir+"\\new");
if (!theDirNew.exists()) theDirNew.mkdirs();
File fileToAddToArchive = new File(args[0]); //file to add to archive
File fileToSave = new File(specialDir+"\\new\\"+fileToAddToArchive.getName());
//file object to create file in specialDir/new
FileOutputStream fileOutputStream = new FileOutputStream(fileToSave);
FileInputStream fileInputStream = new FileInputStream(fileToAddToArchive);
while (fileInputStream.available()>0){
fileOutputStream.write(fileInputStream.read());
}
fileOutputStream.flush();
fileOutputStream.close();
fileInputStream.close();
//2 is done!
//3 - Unzip all files from archive to specialDir directory
File zipFile = new File(args[1]); //archive
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
//stream from archive
ZipEntry a;
while ((a = zipInputStream.getNextEntry())!=null){
if (a.getName().equals("new/" + Paths.get(args[0]).getFileName())) continue;
if (!a.isDirectory()) { //if this is not a directory (this function is not working properly)
String zipfileName = a.getName(); //take file name from zip entry
File newFile = new File(specialDir + "\\" + zipfileName);
//create new file with name from zip entry
FileOutputStream fileOutputStream1 = new FileOutputStream(newFile);
while (zipInputStream.available() > 0) {
fileOutputStream1.write(zipInputStream.read());
}
fileOutputStream1.flush();
fileOutputStream1.close();
}
else { //if this is a directory (not working function)
File nextDir = new File(a.toString());
if (!nextDir.exists()) nextDir.mkdirs(); //then we create a directory with the same name in specialDir
}
}
zipInputStream.closeEntry();
zipInputStream.close();
//3 is done!
//4 - Delete old archive
Files.delete(Paths.get(String.valueOf(zipFile)));
//4 is done!
//5 - Walk file tree specialDir and zip it all to archive with the same name as old one
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(args[1]));
Path source = Paths.get(specialDir);
Files.walkFileTree(source,new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
FileInputStream fileInputStream1 = new FileInputStream(file.toFile());
Path targetFile = source.relativize(file);//I'm not sure about this line
zipOutputStream.putNextEntry(new ZipEntry(targetFile.toString()));
while (fileInputStream1.available()>0){
zipOutputStream.write(fileInputStream1.read());
}
zipOutputStream.closeEntry();
fileInputStream1.close();
return super.visitFile(file, attrs);
}
});
zipOutputStream.closeEntry();
zipOutputStream.close();
//5 is done!
}
}