diff --git a/src/main/java/com/threerings/getdown/classpath/cache/GarbageCollector.java b/src/main/java/com/threerings/getdown/classpath/cache/GarbageCollector.java index 6c1dbc7..48ae7f8 100644 --- a/src/main/java/com/threerings/getdown/classpath/cache/GarbageCollector.java +++ b/src/main/java/com/threerings/getdown/classpath/cache/GarbageCollector.java @@ -20,18 +20,18 @@ public class GarbageCollector File lastAccessedFile = getLastAccessedFile(file); if (!cachedFile.exists() || !lastAccessedFile.exists()) { if (cachedFile.exists()) { - cachedFile.delete(); + FileUtil.deleteHarder(cachedFile); } else { - lastAccessedFile.delete(); + FileUtil.deleteHarder(lastAccessedFile); } } else if (shouldDelete(lastAccessedFile, retentionPeriodMillis)) { - lastAccessedFile.delete(); - cachedFile.delete(); + FileUtil.deleteHarder(lastAccessedFile); + FileUtil.deleteHarder(cachedFile); } File folder = file.getParentFile(); if (folder.list().length == 0) { - folder.delete(); + FileUtil.deleteHarder(folder); } } }); diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java index 685479c..886551f 100644 --- a/src/main/java/com/threerings/getdown/data/Application.java +++ b/src/main/java/com/threerings/getdown/data/Application.java @@ -927,7 +927,7 @@ public class Application // will have to rediscover that it needs updating and reattempt to update itself if (_allowOffline) { log.warning("Failed to update digest files. Attempting offline operaton.", ex); - if (!getLocalPath(VERSION_FILE).delete()) { + if (!FileUtil.deleteHarder(getLocalPath(VERSION_FILE))) { log.warning("Deleting version.txt failed. This probably isn't going to work."); } } else { @@ -1567,7 +1567,7 @@ public class Application signature = StreamUtil.toByteArray(new FileInputStream(signatureFile)); } finally { StreamUtil.close(reader); - signatureFile.delete(); // delete the file regardless + FileUtil.deleteHarder(signatureFile); // delete the file regardless } byte[] buffer = new byte[8192]; @@ -1605,7 +1605,7 @@ public class Application // if we couldn't find a key that validates our digest, we are the hosed! if (validated == 0) { // delete the temporary digest file as we know it is invalid - target.delete(); + FileUtil.deleteHarder(target); throw new IOException("m.corrupt_digest_signature_error"); } } diff --git a/src/main/java/com/threerings/getdown/data/Resource.java b/src/main/java/com/threerings/getdown/data/Resource.java index 6a49a1e..c7281cc 100644 --- a/src/main/java/com/threerings/getdown/data/Resource.java +++ b/src/main/java/com/threerings/getdown/data/Resource.java @@ -91,7 +91,7 @@ public class Resource implements Comparable } } if (tmpJarFile != null) { - tmpJarFile.delete(); + FileUtil.deleteHarder(tmpJarFile); } } @@ -240,7 +240,7 @@ public class Resource implements Comparable */ public void clearMarker () { - if (_marker.exists() && !_marker.delete()) { + if (_marker.exists() && !FileUtil.deleteHarder(_marker)) { log.warning("Failed to erase marker file '" + _marker + "'."); } } @@ -291,7 +291,7 @@ public class Resource implements Comparable public void erase () { clearMarker(); - if (_local.exists() && !_local.delete()) { + if (_local.exists() && !FileUtil.deleteHarder(_local)) { log.warning("Failed to erase resource '" + _local + "'."); } } diff --git a/src/main/java/com/threerings/getdown/launcher/Getdown.java b/src/main/java/com/threerings/getdown/launcher/Getdown.java index 077490e..03743b7 100644 --- a/src/main/java/com/threerings/getdown/launcher/Getdown.java +++ b/src/main/java/com/threerings/getdown/launcher/Getdown.java @@ -722,7 +722,7 @@ public abstract class Getdown extends Thread } // clean up the patch file - if (!prsrc.getLocal().delete()) { + if (!FileUtil.deleteHarder(prsrc.getLocal())) { log.warning("Failed to delete '" + prsrc + "'."); prsrc.getLocal().deleteOnExit(); } diff --git a/src/main/java/com/threerings/getdown/util/FileUtil.java b/src/main/java/com/threerings/getdown/util/FileUtil.java index d14de11..f59e8bc 100644 --- a/src/main/java/com/threerings/getdown/util/FileUtil.java +++ b/src/main/java/com/threerings/getdown/util/FileUtil.java @@ -45,12 +45,12 @@ public class FileUtil // place and then delete the old file if (dest.exists()) { File temp = new File(dest.getPath() + "_old"); - if (temp.exists() && !temp.delete()) { + if (temp.exists() && !deleteHarder(temp)) { log.warning("Failed to delete old intermediate file " + temp + "."); // the subsequent code will probably fail } if (dest.renameTo(temp) && source.renameTo(dest)) { - if (!temp.delete()) { + if (!deleteHarder(temp)) { log.warning("Failed to delete intermediate file " + temp + "."); } return true; @@ -67,7 +67,7 @@ public class FileUtil // close the input stream now so we can delete 'source' fin.close(); fin = null; - if (!source.delete()) { + if (!deleteHarder(source)) { log.warning("Failed to delete " + source + " after brute force copy to " + dest + "."); } @@ -83,6 +83,18 @@ public class FileUtil } } + /** + * "Tries harder" to delete {@code file} than just calling {@code delete} on it. Presently this + * just means "try a second time if the first time fails." On Windows Vista, sometimes deletes + * fail but then succeed if you just try again. Given that delete failure is a rare occurance, + * we can implement this hacky workaround without any negative consequences for normal + * behavior. + */ + public static boolean deleteHarder (File file) { + // if at first you don't succeed... try, try again + return file.delete() || file.delete(); + } + /** * Reads the contents of the supplied input stream into a list of lines. Closes the reader on * successful or failed completion. diff --git a/src/main/java/com/threerings/getdown/util/LaunchUtil.java b/src/main/java/com/threerings/getdown/util/LaunchUtil.java index 92c6d10..e60abb4 100644 --- a/src/main/java/com/threerings/getdown/util/LaunchUtil.java +++ b/src/main/java/com/threerings/getdown/util/LaunchUtil.java @@ -144,13 +144,13 @@ public class LaunchUtil // clear out any old getdown if (oldgd.exists()) { - oldgd.delete(); + FileUtil.deleteHarder(oldgd); } // now try updating using renames if (!curgd.exists() || curgd.renameTo(oldgd)) { if (newgd.renameTo(curgd)) { - oldgd.delete(); // yay! + FileUtil.deleteHarder(oldgd); // yay! try { // copy the moved file back to getdown-dop-new.jar so that we don't end up // downloading another copy next time