From 50c1cfa5726c79d5184a0c9d258afb159a5e0899 Mon Sep 17 00:00:00 2001 From: "Jesse N. Glick" Date: Mon, 27 Feb 2012 22:16:41 +0000 Subject: [PATCH] #52742: safer stream closing. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1294360 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tools/ant/taskdefs/Replace.java | 138 ++++++++---------- 1 file changed, 60 insertions(+), 78 deletions(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java index 40d764300..4ae791cde 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Replace.java +++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java @@ -23,11 +23,10 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; @@ -351,8 +350,9 @@ public class Replace extends MatchingTask { * a StringBuffer. Compatible with the Replacefilter. * @since 1.7 */ - private class FileInput { + private class FileInput /* JDK 5: implements Closeable */ { private StringBuffer outputBuffer; + private final InputStream is; private Reader reader; private char[] buffer; private static final int BUFF_SIZE = 4096; @@ -365,11 +365,13 @@ public class Replace extends MatchingTask { FileInput(File source) throws IOException { outputBuffer = new StringBuffer(); buffer = new char[BUFF_SIZE]; - if (encoding == null) { - reader = new BufferedReader(new FileReader(source)); - } else { - reader = new BufferedReader(new InputStreamReader( - new FileInputStream(source), encoding)); + is = new FileInputStream(source); + try { + reader = new BufferedReader(encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is)); + } finally { + if (reader == null) { + is.close(); + } } } @@ -401,15 +403,8 @@ public class Replace extends MatchingTask { * Closes the file. * @throws IOException When the file cannot be closed. */ - void close() throws IOException { - reader.close(); - } - - /** - * Closes file but doesn't throw exception - */ - void closeQuietly() { - FileUtils.close(reader); + public void close() throws IOException { + is.close(); } } @@ -419,8 +414,9 @@ public class Replace extends MatchingTask { * Replacefilter. * @since 1.7 */ - private class FileOutput { + private class FileOutput /* JDK 5: implements Closeable */ { private StringBuffer inputBuffer; + private final OutputStream os; private Writer writer; /** @@ -429,12 +425,14 @@ public class Replace extends MatchingTask { * @throws IOException When the file cannot be read from. */ FileOutput(File out) throws IOException { - if (encoding == null) { - writer = new BufferedWriter(new FileWriter(out)); - } else { - writer = new BufferedWriter(new OutputStreamWriter - (new FileOutputStream(out), encoding)); + os = new FileOutputStream(out); + try { + writer = new BufferedWriter(encoding != null ? new OutputStreamWriter(os, encoding) : new OutputStreamWriter(os)); + } finally { + if (writer == null) { + os.close(); } + } } /** @@ -475,16 +473,10 @@ public class Replace extends MatchingTask { * Closes the file. * @throws IOException When the file cannot be closed. */ - void close() throws IOException { - writer.close(); + public void close() throws IOException { + os.close(); } - /** - * Closes file but doesn't throw exception - */ - void closeQuietly() { - FileUtils.close(writer); - } } /** @@ -665,62 +657,52 @@ public class Replace extends MatchingTask { + " doesn't exist", getLocation()); } - File temp = null; - FileInput in = null; - FileOutput out = null; - try { - in = new FileInput(src); + int repCountStart = replaceCount; + logFilterChain(src.getPath()); - temp = FILE_UTILS.createTempFile("rep", ".tmp", + try { + File temp = FILE_UTILS.createTempFile("rep", ".tmp", src.getParentFile(), false, true); - out = new FileOutput(temp); - - int repCountStart = replaceCount; - - logFilterChain(src.getPath()); - - out.setInputBuffer(buildFilterChain(in.getOutputBuffer())); - - while (in.readChunk()) { - if (processFilterChain()) { - out.process(); + try { + FileInput in = new FileInput(src); + try { + FileOutput out = new FileOutput(temp); + try { + out.setInputBuffer(buildFilterChain(in.getOutputBuffer())); + + while (in.readChunk()) { + if (processFilterChain()) { + out.process(); + } + } + + flushFilterChain(); + + out.flush(); + } finally { + out.close(); + } + } finally { + in.close(); } - } - - flushFilterChain(); - - out.flush(); - in.close(); - in = null; - out.close(); - out = null; - - boolean changes = (replaceCount != repCountStart); - if (changes) { - fileCount++; - long origLastModified = src.lastModified(); - FILE_UTILS.rename(temp, src); - if (preserveLastModified) { - FILE_UTILS.setFileLastModified(src, origLastModified); + boolean changes = (replaceCount != repCountStart); + if (changes) { + fileCount++; + long origLastModified = src.lastModified(); + FILE_UTILS.rename(temp, src); + if (preserveLastModified) { + FILE_UTILS.setFileLastModified(src, origLastModified); + } + } + } finally { + if (temp.isFile() && !temp.delete()) { + temp.deleteOnExit(); } - temp = null; } } catch (IOException ioe) { throw new BuildException("IOException in " + src + " - " + ioe.getClass().getName() + ":" + ioe.getMessage(), ioe, getLocation()); - } finally { - if (null != in) { - in.closeQuietly(); - } - if (null != out) { - out.closeQuietly(); - } - if (temp != null) { - if (!temp.delete()) { - temp.deleteOnExit(); - } - } } }