So I have this code, it pretty much does what it should but my archive ends up broken and it doesn't save the files. Of course I have to achieve these without using FileSystem, no TempFiles
or anything.
public static void main(String[] args) throws IOException {
// Path fileName = Paths.get(args[0]);
// String pathZip = args[1];
Path fileName = Paths.get("C:\\Users\\dell\\Desktop\\addfile.txt");
String pathZip = "C:\\Users\\dell\\Desktop\\test.zip";
Map<String, byte[]> zipEntryMap = addFilesInMap(pathZip);
zipEntryMap.forEach((zipEntryName, bytes) -> {
System.out.println(zipEntryName+" "+bytes.toString());
try {
containAndSaveSameFiles(pathZip, bytes, zipEntryName);
} catch (Exception e) {
e.printStackTrace();
}
});
// saveFileInArchive(fileName, pathZip);
}
private static Map<String, byte[]> addFilesInMap(String pathZip) throws IOException {
Map<String, byte[]> zipEntryMap = new HashMap<>();
FileInputStream fileInputStream = new FileInputStream(pathZip);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
ZipEntry zipEntry;
while((zipEntry = zipInputStream.getNextEntry())!= null){
byte[] buffer = new byte[1024];
ByteArrayOutputStream builder = new ByteArrayOutputStream();
int end;
while((end = zipInputStream.read(buffer)) > 0){
builder.write(buffer, 0, end);
}
zipEntryMap.put(zipEntry.getName(), builder.toByteArray());
}
return zipEntryMap;
}
private static void containAndSaveSameFiles(String pathZip, byte[] bytes, String zipEntryName) throws Exception{
ByteArrayOutputStream readBytes = new ByteArrayOutputStream();
FileOutputStream fileOutputStream = new FileOutputStream(pathZip);
ZipOutputStream outputStream = new ZipOutputStream(readBytes);
ZipEntry zipEntry2 = new ZipEntry(zipEntryName);
zipEntry2.setSize(bytes.length);
outputStream.putNextEntry(new ZipEntry(zipEntryName));
outputStream.write(bytes);
}
private static void saveFileInArchive(Path fileToBeAdded, String pathToArchive) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(pathToArchive);
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
zipOutputStream.putNextEntry(new ZipEntry("new/"+fileToBeAdded.getFileName()));
Files.copy(fileToBeAdded, zipOutputStream);
zipOutputStream.close();
fileOutputStream.close();
}
I tried a few ways, and look up on the internet but can't find any good answer. Thank you for help.
Your code is almost correct.
Bug No:1 in containAndSaveSameFiles
Using readBytes instead of fileOutputStream.
Bug No:2 in saveFileInArchive
Rewriting OutputStream by reopening it again.
Complete code after review:
public static void main(String[] args) throws IOException {
// Path fileName = Paths.get(args[0]);
// String pathZip = args[1];
Path fileName = Paths.get("C:\\Users\\dell\\Desktop\\addfile.txt");
String pathZip = "C:\\Users\\dell\\Desktop\\test.zip";
Map<String, byte[]> zipEntryMap = addFilesInMap(pathZip);
FileOutputStream fileOutputStream = new FileOutputStream(pathZip);
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
zipEntryMap.forEach((zipEntryName, bytes) -> {
System.out.println(zipEntryName+" "+bytes.toString());
try {
containAndSaveSameFiles(pathZip, bytes, zipEntryName, zipOutputStream);
} catch (Exception e) {
e.printStackTrace();
}
});
saveFileInArchive(fileName, pathZip,zipOutputStream);
zipOutputStream.close();
fileOutputStream.close();
}
private static Map<String, byte[]> addFilesInMap(String pathZip) throws IOException {
Map<String, byte[]> zipEntryMap = new HashMap<>();
FileInputStream fileInputStream = new FileInputStream(pathZip);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
ZipEntry zipEntry;
while((zipEntry = zipInputStream.getNextEntry())!= null){
byte[] buffer = new byte[1024];
ByteArrayOutputStream builder = new ByteArrayOutputStream();
int end;
while((end = zipInputStream.read(buffer)) > 0){
builder.write(buffer, 0, end);
}
zipEntryMap.put(zipEntry.getName(), builder.toByteArray());
}
return zipEntryMap;
}
private static void containAndSaveSameFiles(String pathZip, byte[] bytes, String zipEntryName, ZipOutputStream zipOutputStream) throws Exception{
// ByteArrayOutputStream readBytes = new ByteArrayOutputStream();
ZipEntry zipEntry2 = new ZipEntry(zipEntryName);
zipEntry2.setSize(bytes.length);
zipOutputStream.putNextEntry(new ZipEntry(zipEntryName));
zipOutputStream.write(bytes);
}
private static void saveFileInArchive(Path fileToBeAdded, String pathToArchive, ZipOutputStream zipOutputStream) throws IOException, IOException {
zipOutputStream.putNextEntry(new ZipEntry("new/"+fileToBeAdded.getFileName()));
Files.copy(fileToBeAdded, zipOutputStream);
}