From de78c1116e61e6a112f96949756c9b66a3448c24 Mon Sep 17 00:00:00 2001 From: CrushedPixel Date: Tue, 2 Jun 2015 20:33:51 +0200 Subject: [PATCH] The ReplayFileAppender now changes Replay Files in one go (on Windows machines) if there is already a File to be added --- .../registry/ReplayFileAppender.java | 56 ++++++++++++------ .../replaymod/utils/ReplayFileIO.java | 58 +++++++++++-------- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/main/java/eu/crushedpixel/replaymod/registry/ReplayFileAppender.java b/src/main/java/eu/crushedpixel/replaymod/registry/ReplayFileAppender.java index de188dc6..a7711778 100644 --- a/src/main/java/eu/crushedpixel/replaymod/registry/ReplayFileAppender.java +++ b/src/main/java/eu/crushedpixel/replaymod/registry/ReplayFileAppender.java @@ -1,5 +1,7 @@ package eu.crushedpixel.replaymod.registry; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; import eu.crushedpixel.replaymod.gui.GuiReplaySaving; import eu.crushedpixel.replaymod.utils.ReplayFileIO; import net.minecraft.client.Minecraft; @@ -7,14 +9,14 @@ import net.minecraftforge.fml.client.FMLClientHandler; import org.apache.commons.lang3.tuple.Pair; import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; public class ReplayFileAppender extends Thread { - private Queue, File>> filesToMove = new ConcurrentLinkedQueue, File>>(); + private Multimap> filesToMove = ArrayListMultimap.create(); + private Queue filesToRewrite = new ConcurrentLinkedQueue(); + private boolean shutdown = false; private List listeners = new ArrayList(); @@ -50,43 +52,59 @@ public class ReplayFileAppender extends Thread { } public void registerModifiedFile(File toAdd, String name, File replayFile) { - for(Pair, File> p : new ArrayList, File>>(filesToMove)) { - if(p.getLeft().getRight().equals(name) && p.getRight().equals(replayFile)) { - filesToMove.remove(p); + //first, remove any files with the same name assigned to this Replay File + if(filesToMove.get(replayFile) != null) { + for(Pair p : new ArrayList>((Collection>)filesToMove.get(replayFile))) { + if(p.getRight().equals(name)) { + filesToMove.remove(replayFile, p); + } } } - filesToMove.add(Pair.of(Pair.of(toAdd, name), replayFile)); + //then, assign the file/name pair to the Replay File + filesToMove.put(replayFile, Pair.of(toAdd, name)); + + //finally, add the Replay File to the Queue if not already contained + if(!filesToRewrite.contains(replayFile)) { + filesToRewrite.add(replayFile); + } } public void shutdown() { shutdown = true; } - public boolean isBusy() { - return !filesToMove.isEmpty() && !newReplayFileWriting; - } - public void addFinishListener(GuiReplaySaving gui) { listeners.add(gui); } @Override public void run() { - while(!shutdown || !filesToMove.isEmpty()) { - Pair, File> mv = filesToMove.poll(); - if(mv != null) { - if(mv.getRight().canWrite()) { + while(!shutdown || !filesToRewrite.isEmpty()) { + File replayFile = filesToRewrite.poll(); + if(replayFile != null) { + if(replayFile.canWrite()) { try { - ReplayFileIO.addFileToZip(mv.getRight(), mv.getLeft().getLeft(), mv.getLeft().getRight()); + HashMap toAdd = new HashMap(); + for(Pair p : filesToMove.get(replayFile)) { + toAdd.put(p.getRight(), p.getLeft()); + } + ReplayFileIO.addFilesToZip(replayFile, toAdd); + + //delete all written files + for(Pair p : filesToMove.get(replayFile)) { + p.getLeft().delete(); + } + filesToMove.removeAll(replayFile); } catch(Exception e) { e.printStackTrace(); - filesToMove.add(mv); + filesToRewrite.add(replayFile); } finally { callListeners(); } + } else { - filesToMove.add(mv); + filesToRewrite.add(replayFile); } } try { diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java index 7048226f..8a8dd1b5 100755 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java @@ -20,10 +20,7 @@ import org.apache.commons.io.IOUtils; import java.io.*; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -317,7 +314,14 @@ public class ReplayFileIO { Files.write(file.toPath(), json.getBytes()); } - public static void addFileToZip(File zipFile, File toAdd, String fileName) throws IOException { + /** + * Adds Files as entries to a ZIP File. + * @param zipFile The ZIP File to add the files to. + * @param toAdd A Map containing the file's desired names as the keys and the files themselves as the values. + * Files may be null in order to remove entries with the respective name from the ZIP File. + * @throws IOException + */ + public static void addFilesToZip(File zipFile, HashMap toAdd) throws IOException { // get a temp file File tempFile = File.createTempFile(zipFile.getName(), null, zipFile.getParentFile()); // delete it, otherwise you cannot rename your existing zip to it. @@ -328,13 +332,15 @@ public class ReplayFileIO { ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempFile)); ZipEntry entry = zin.getNextEntry(); + while(entry != null) { String name = entry.getName(); - boolean isFile = name.equalsIgnoreCase(fileName); - if(!isFile) { - // Add ZIP entry to output stream. + + // Don't rewrite (keep) the old file if one of the new files uses the same name + boolean willBeOverwritten = toAdd.containsKey(name); + if(!willBeOverwritten) { out.putNextEntry(new ZipEntry(name)); - // Transfer bytes from the ZIP file to the output file + // Transfer bytes from the ZIP entry to the output entry int len; while((len = zin.read(buf)) > 0) { out.write(buf, 0, len); @@ -346,23 +352,29 @@ public class ReplayFileIO { zin.close(); // Compress the files - if(toAdd != null) { - InputStream in = new FileInputStream(toAdd); - // Add ZIP entry to output stream. - out.putNextEntry(new ZipEntry(fileName)); - // Transfer bytes from the file to the ZIP file + // Write all files to Replay File + if(!toAdd.isEmpty()) { + for(Map.Entry e : toAdd.entrySet()) { + String fileName = e.getKey(); + File toWrite = e.getValue(); - int len; - if(fileName.equals("thumb")) out.write(uniqueBytes); + // The File may be null to simply be removed + if(toWrite != null) { + InputStream in = new FileInputStream(toWrite); + // Add ZIP entry to output stream. + out.putNextEntry(new ZipEntry(fileName)); - while((len = in.read(buf)) > 0) { - out.write(buf, 0, len); + int len; + if(fileName.equals("thumb")) out.write(uniqueBytes); + + while((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + // Complete the entry + out.closeEntry(); + in.close(); + } } - // Complete the entry - out.closeEntry(); - in.close(); - - toAdd.delete(); } // Complete the ZIP file