diff --git a/common/src/main/java/org/sonatype/goodies/common/FileReplacer.java b/common/src/main/java/org/sonatype/goodies/common/FileReplacer.java index 71fecb7e..56643dfb 100644 --- a/common/src/main/java/org/sonatype/goodies/common/FileReplacer.java +++ b/common/src/main/java/org/sonatype/goodies/common/FileReplacer.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; +import com.google.common.base.Throwables; import com.google.common.io.Files; import org.slf4j.Logger; @@ -45,7 +46,7 @@ public class FileReplacer private boolean deleteBackupFile; - public FileReplacer(final File file) throws IOException { + public FileReplacer(final File file) { this.file = checkNotNull(file); // not using File.createTempFile() here so tmp + backup can share same timestamp-id @@ -55,15 +56,6 @@ public FileReplacer(final File file) throws IOException { this.filePrefix = file.getName() + "-" + System.currentTimeMillis() + "-" + counter.getAndIncrement(); this.tempFile = new File(file.getParentFile(), filePrefix + ".tmp"); this.backupFile = new File(file.getParentFile(), filePrefix + ".bak"); - - file.getParentFile().mkdirs(); - - if (tempFile.exists()) { - log.warn("Temporary file already exists; removing: {}", tempFile); - delete(tempFile); - } - - tempFile.createNewFile(); } public FileReplacer(final String fileName) throws IOException { @@ -77,6 +69,13 @@ private void delete(final File file) throws IOException { } } + private void create(final File file) throws IOException { + boolean created = file.createNewFile(); + if (!created) { + throw new IOException("Failed to create file: " + file); + } + } + public File getFile() { return file; } @@ -97,7 +96,7 @@ public void setDeleteBackupFile(final boolean deleteBackupFile) { this.deleteBackupFile = deleteBackupFile; } - public static interface ContentWriter + public interface ContentWriter { void write(final BufferedOutputStream output) throws IOException; } @@ -105,27 +104,36 @@ public static interface ContentWriter public void replace(final ContentWriter writer) throws IOException { checkNotNull(writer); - // setup buffering, as almost certainly anywhere using this class is going to want this - BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile)); + // prepare directory structure + file.getParentFile().mkdirs(); + + // prepare temporary file + if (tempFile.exists()) { + log.warn("Temporary file already exists; removing: {}", tempFile); + delete(tempFile); + } + create(tempFile); - // delegate to do the write operation try { - try { + // delegate to do the write operation + try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile))) { writer.write(output); } - finally { - // always close after success or failure - output.close(); + catch (Exception e) { + // complain with details about temp file and propagate exception + log.warn("Failed to write temporary file: {}", tempFile, e); + Throwables.propagateIfPossible(e, IOException.class); + throw Throwables.propagate(e); } + + // replace the file only if operation succeeded + replaceFile(); } - catch (IOException e) { - // complain with details about temp file and propagate exception - log.warn("Failed to write temporary file: {}", tempFile, e); - throw e; + finally { + if (tempFile.exists()) { + delete(tempFile); + } } - - // replace the file only if operation succeeded - replaceFile(); } private void replaceFile() throws IOException {